圧センサーで打ち上げ花火
花火が下から打ち上がり、一定の高さに達したら「ひまわり」のような螺旋パターンで花火が爆発するコード例です。圧センサーでなくとも、他のセンサーでも実施可能です。
【ポイント】
- ロケットフェーズ:画面下部から上昇する花火の玉を表現します。
- 爆発フェーズ:ロケットが一定の高さに達すると、黄金角(約137.5°)を利用した螺旋パターンでパーティクルを生成し、ひまわりのような花火の形にします。
リハビリ場面での想定
例1:シンプルにプロジェクターなど使用し、レクリエーションなどで活用
壁などにセンサーを仕掛けることで、前方リーチの訓練になる。
例2:拍手などの音を拾い、その数値の変化で花火をあげる場合は、タイミングや周囲との協調の促進などの練習となる。
例3:力を鍛えたい部分の出力などを数値として拾うことで、視覚的フィードバックとなる。
アイデア次第で様々な場面に活かすことが可能です。
Arduino側の設定
センサー(例:アナログ入力A0)からの値が一定の閾値(ここでは500を例示)を超えた場合に「TRIGGER」を送信するコードです。
Arduinoコード
// 圧センサー用のピン設定(A0を使用)
int sensorPin = A0;
int threshold = 500; // 圧力の閾値(適宜調整してください)
void setup() {
Serial.begin(9600); // シリアル通信を開始
}
void loop() {
int sensorValue = analogRead(sensorPin); // センサーの値を読み取る
Serial.println(sensorValue); // センサー値をシリアルモニタに出力(デバッグ用)
// センサーの値が閾値を超えたら "TRIGGER" を送信
if (sensorValue > threshold) {
Serial.println("TRIGGER");
delay(1000); // トリガー後、1秒待機して多重送信を防止
}
delay(100); // 少し待機してから再度読み取り
}
Python側の設定
Pythonコード
import serial
import pygame
import sys
import random
import math
# --- シリアル通信の設定 ---
SERIAL_PORT = 'COM3' # 環境に合わせて変更してください
BAUD_RATE = 9600
try:
ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=1)
except Exception as e:
print(f"シリアルポート {SERIAL_PORT} に接続できませんでした: {e}")
sys.exit()
# --- Pygameの初期設定 ---
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Sunflower Fireworks")
clock = pygame.time.Clock()
# 背景画像の読み込み(なければ黒背景)
try:
background = pygame.image.load("background.jpg").convert()
background = pygame.transform.scale(background, (WIDTH, HEIGHT))
except Exception as e:
print("背景画像が見つかりません。背景は黒になります。")
background = None
# --- Fireworkクラス(ロケットとひまわり爆発) ---
class Firework:
def __init__(self, x, target_y):
self.x = x
self.y = HEIGHT # ロケットは画面下部から発射
self.target_y = target_y # 爆発する高さ
self.vy = -8 # 上向きの初速度
self.exploded = False
self.particles = [] # 爆発後のパーティクルリスト
def update(self):
if not self.exploded:
# ロケット上昇フェーズ
self.y += self.vy
if self.y <= self.target_y: self.explode() else: # 爆発パーティクルの更新 for p in self.particles: p[0] += p[2] # x座標更新 p[1] += p[3] # y座標更新 p[3] += 0.05 # ゆるやかな重力効果(y方向) p[4] -= 0.05 # パーティクルのサイズが徐々に減少 self.particles = [p for p in self.particles if p[4] > 0]
def explode(self):
self.exploded = True
num_particles = 150 # パーティクル数(調整可能)
golden_angle = math.radians(137.5)
# 黄金角を利用したひまわりパターンの生成
for i in range(num_particles):
angle = i * golden_angle
# パーティクルの速度は sqrt(i) に比例(調整可能)
speed = 3 + (math.sqrt(i) * 0.2)
vx = speed * math.cos(angle)
vy = speed * math.sin(angle)
size = random.randint(4, 8) # 初期サイズ(調整可能)
self.particles.append([self.x, self.y, vx, vy, size])
def draw(self, surface):
if not self.exploded:
# 上昇中のロケットを小さな白い円で描画
pygame.draw.circle(surface, (255, 255, 255), (int(self.x), int(self.y)), 3)
else:
# 爆発パーティクルの描画(ランダムな色)
for p in self.particles:
color = (255, random.randint(100, 255), random.randint(100, 255))
pygame.draw.circle(surface, color, (int(p[0]), int(p[1])), int(p[4]))
fireworks = []
def trigger_firework():
# ランダムなx座標と、爆発する高さ(上半分)を設定
x = random.randint(100, WIDTH - 100)
target_y = random.randint(100, HEIGHT // 2)
fireworks.append(Firework(x, target_y))
def main():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
ser.close()
pygame.quit()
sys.exit()
# 背景描画
if background:
screen.blit(background, (0, 0))
else:
screen.fill((0, 0, 0))
# Arduinoからのシリアルデータを監視
if ser.in_waiting:
try:
line = ser.readline().decode('utf-8').strip()
except UnicodeDecodeError:
line = ""
if line == "TRIGGER":
trigger_firework()
# 花火の更新と描画
for fw in fireworks:
fw.update()
fw.draw(screen)
# 完全に終了した花火はリストから除去
fireworks[:] = [fw for fw in fireworks if (not fw.exploded) or (fw.particles)]
pygame.display.flip()
clock.tick(60) # 60FPS
if __name__ == "__main__":
main()
【コード解説】
Fireworkクラス
- 花火の玉のフェーズ:
self.y
は画面下部から上昇し、target_y
に達するとexplode()
を呼び出して爆発を開始します。 - 爆発フェーズ:黄金角を用いて150個のパーティクルを生成。各パーティクルは螺旋状の方向に初期速度が与えられ、徐々にサイズが縮小して消えていきます。
- 花火の玉のフェーズ:
trigger_firework() 関数
- シリアルから「TRIGGER」が受信されると、ランダムな位置と爆発高さで新たな花火を生成します。
main() 関数
- シリアルデータの監視、背景描画、花火の更新&描画を行い、60FPSでループします。
このコードで、花火は下部から上昇し、一定の高さでひまわりのような螺旋パターンの爆発を行います。必要に応じて数値(速度、パーティクル数、サイズなど)を調整して、お好みの演出にカスタマイズしてください。
コメント