見出し画像

ChatGPTにPyxelを教えてもらう(花火)

ChatGPTに花火のプログラムをお願いしてみた結果



ChatGPTの返答

Pyxelを使用して、花火を描くプログラムを作成する例を以下に示します。このプログラムでは、花火の打ち上げと爆発をシミュレートします。

1. FireworkParticle クラスは、花火の粒子を表し、位置、速度、角度、および色を持ちます。粒子は更新されるときに減速し、速度が小さくなると消えます。
2. Firework クラスは花火を表し、打ち上げと爆発の状態を管理します。一定の高さに達すると爆発し、粒子を生成します。
3. App クラスはPyxelアプリケーションのメインクラスで、定期的に新しい花火を打ち上げ、すべての花火と粒子を更新および描画します。

このコードを実行すると、Pyxelウィンドウに花火が打ち上がり、空中で爆発して粒子が広がる様子が描画されます。


少し手直しして乱数や三角関数はPyxelのものを使用。
リストにクラスのインスタンスを格納するとインスタンスのメソッドを呼び出せると初めて知った。。

import pyxel

class FireworkParticle:     # 花火の粒子
    def __init__(self, x, y, angle, speed, color):
        self.x = x
        self.y = y
        self.angle = angle
        self.speed = speed
        self.color = color
        self.alive = True

    def update(self):
        self.x += self.speed * pyxel.cos(self.angle)
        self.y += self.speed * pyxel.sin(self.angle)
        self.speed *= 0.98  # 減速
        if self.speed < 0.3:
            self.alive = False # 点が広がったら消える

    def draw(self):
        if self.alive:
            pyxel.pset(self.x, self.y, self.color)

class Firework:             # 花火
    def __init__(self, x, y, color):
        self.x = x
        self.y = y
        self.color = color
        self.particles = []
        self.exploded = False   # 花火が開いたかどうか

    def update(self):
        if not self.exploded:   # 花火が開く前
            self.y -= 2
            if self.y < pyxel.rndi(40, 70): # 花火が開く位置
                self.explode()              # 花火を開く
                pyxel.play(0, 0)            # 花火が開く音を鳴らす
        else:                   # 花火が開いた後
            for particle in self.particles:
                particle.update()

    def explode(self):          
        self.exploded = True
        for _ in range(100):    # 花火の粒子を円上に配置
            angle = pyxel.rndi(0, 360)
            speed = pyxel.rndf(1, 3)
            # FireworkParticle クラスのインスタンスをリストに追加
            self.particles.append(FireworkParticle(self.x, self.y, angle, speed, self.color))

    def draw(self):
        if not self.exploded:   # 花火が開く前
            pyxel.pset(self.x, self.y, self.color)  # まっすぐ上に上がる
        else:                   # 花火が開いた後
            for particle in self.particles:         # 花火の粒子を描く
                particle.draw()

class App:
    def __init__(self):
        pyxel.init(256, 256, title="Fireworks")
        self.fireworks = []
        self.launch_interval = 30
        self.launch_timer = 0
        pyxel.sounds[0].set("f3d3c3c3c3", "n", "32222", "n", 10) # 花火の音
        pyxel.run(self.update, self.draw)

    def update(self):
        self.launch_timer += 1
        if self.launch_timer > self.launch_interval:
            self.launch_timer = 0
            self.launch_firework()

        for firework in self.fireworks:
            firework.update()

    def draw(self):
        pyxel.cls(pyxel.COLOR_BLACK)
        for firework in self.fireworks:
            firework.draw()

    def launch_firework(self):  # 花火打ち上げ
        x = pyxel.rndi(15, 240)     # 花火を打ち上げる位置 
        y = 200
        color = pyxel.rndi(8, 15)   # 花火の色
        self.fireworks.append(Firework(x, y, color))

App()

ちょっと修正版(2024.7.15)

画面のサイズや速度を修正してみました
花火が上がる「ヒュー」という音が出せない

import pyxel

EXPLOSION_SOUND = ("b3c3g2g2", "n", "4322", "f", 10)    # 花火が開く音
SHOOT_SOUND     = ("rrrre3a3a3", "p", "1", "ffs", 8)    # 花火が上がる音

class FireworkParticle:     # 花火の粒子
    def __init__(self, x, y, angle, speed, color):
        self.x = x
        self.y = y
        self.angle = angle
        self.speed = speed
        self.color = color
        self.alive = True

    def update(self):
        self.x += self.speed * pyxel.cos(self.angle)
        self.y += self.speed * pyxel.sin(self.angle)
        self.speed *= 0.98      # 減速
        if self.speed < 0.3:
            self.alive = False  # 点が広がったら消える

    def draw(self):
        if self.alive:
            pyxel.pset(self.x, self.y, self.color)

class Firework:             # 花火
    def __init__(self, x, y, color):
        self.x = x
        self.y = y
        self.color = color
        self.particles = []
        self.exploded = False   # 花火が開いたかどうか

    def update(self):
        if not self.exploded:   # 花火が開く前
            self.y -= 2
            if self.y < pyxel.rndi(40, 80): # 花火が開く位置
                self.explode()              # 花火を開く
                pyxel.play(0, 0)            # 花火が開く音を鳴らす
        else:                   # 花火が開いた後
            for particle in self.particles:
                particle.update()

    def explode(self):          
        self.exploded = True
        for _ in range(100):                # 花火の粒子を配置
            angle = pyxel.rndi(0, 360)
            speed = pyxel.rndf(1, 2)
            # FireworkParticle クラスのインスタンスをリストに追加
            self.particles.append(FireworkParticle(self.x, self.y, angle, speed, self.color))

    def draw(self):
        if not self.exploded:   # 花火が開く前
            pyxel.pset(self.x, self.y, self.color)  # まっすぐ上に上がる
        else:                   # 花火が開いた後
            for particle in self.particles:         # 花火の粒子を描く
                particle.draw()

class App:
    def __init__(self):
        pyxel.init(180, 256, title="Fireworks")
        
        pyxel.sounds[0].set(*EXPLOSION_SOUND)   # 花火が開く音
        pyxel.sounds[1].set(*SHOOT_SOUND)       # 花火が上がる音

        self.fireworks = []
        self.launch_interval = 18
        self.launch_timer = 0

        pyxel.run(self.update, self.draw)

    def update(self):
        self.launch_timer += 1
        if self.launch_timer > self.launch_interval:
            self.launch_timer = 0
            self.launch_firework()
            pyxel.play(1, 1)                    # 花火が上がる音を鳴らす

        for firework in self.fireworks:
            firework.update()

    def draw(self):
        pyxel.cls(pyxel.COLOR_BLACK)
        for firework in self.fireworks:
            firework.draw()

    def launch_firework(self):  # 花火打ち上げ
        x = pyxel.rndi(20, pyxel.width-20)     # 花火を打ち上げる位置 
        y = 200
        color = pyxel.rndi(8, 12)   # 花火の色
        self.fireworks.append(Firework(x, y, color))

App()

この記事が気に入ったらサポートをしてみませんか?