ScratchからPythonへ・・・その2 紙吹雪が一言でできた!
経緯
前に紙吹雪のプログラムを作ってもらった。Scratch的に初歩的な段階から作っていった。どういうことが生成AIは得意か不得意かを知りたいと思っている。生成AIは簡単なことはさらさらとやってくれるが、どうも分岐の問題は苦手のようである。
そこで、今回は紙吹雪の問題を直接お願いしてみた。
なお今回のリートン(wrtn:GPT-4 turbo)を使っている
紙吹雪のプログラム
まずは、つぎの質問をしてみた。ちゃんとプログラムを書いてくれないことがあるので最初にベテランプログラマーとしてお願いした。
帰ってきた回答は次の通りです。謙虚な人ですね。
そしてコードです。
import pygame
import random
# Pygameの初期化
pygame.init()
# 色の設定
WHITE = (255, 255, 255)
COLORS = [(255, 0, 0), (0, 255, 0), (0, 0, 255),
(255, 255, 0), (255, 0, 255), (0, 255, 255)]
# スクリーンサイズの設定
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("紙吹雪のシミュレーション")
# 紙片を表すクラス
class Confetti:
def __init__(self, x, y, color):
self.x = x
self.y = y
self.color = color
self.size = random.randint(5, 10)
self.shape = random.choice(['rect', 'circle'])
self.vel_x = random.randint(-3, 3)
self.vel_y = random.randint(1, 6)
def draw(self, screen):
if self.shape == 'rect':
pygame.draw.rect(screen, self.color, (self.x, self.y, self.size, self.size))
else:
pygame.draw.circle(screen, self.color, (self.x, self.y), self.size // 2)
def fall(self):
self.x += self.vel_x
self.y += self.vel_y
# 画面外に出たら、上に戻す
if self.y > SCREEN_HEIGHT:
self.y = 0
self.x = random.randint(0, SCREEN_WIDTH)
# 紙吹雪のリストの生成
confetti_list = [Confetti(random.randint(0, SCREEN_WIDTH), random.randint(0, SCREEN_HEIGHT), random.choice(COLORS)) for _ in range(100)]
# メインループ
running = True
while running:
screen.fill(WHITE) # 画面を白でクリア
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 紙吹雪の描画と更新
for confetti in confetti_list:
confetti.draw(screen)
confetti.fall()
pygame.display.flip() # 描画内容をスクリーンに適用
pygame.time.Clock().tick(30) # フレームレートを30に設定
pygame.quit() # Pygameの終了
そして、結果です。
素晴らしいですね。一言のお願いでプログラムができてしまいました。
分析
このコードでリストというのがわかりにくかったのでちょっと聞いてみました。
リートンは次の回答をしてくれました。僕の期待していたこととは違ったのですが、コードの構造ということで付け加えておきます。その前にここでリストを使っているのはScratchのクローンですね。最初、一番上から降ってくるのではなく、最初、100個の紙片をランダムに配置してそこから下に落ちていくということで画面にランダムに落ちてくるのがハッキリします。
プログラム構造
関数として保存
一言で紙吹雪ができるのなら、関数として保存してほかの作品に使いたい。
import pygame
import random
# 紙吹雪の設定をするためのクラス
class Confetti:
def __init__(self, screen):
self.screen = screen
self.x = random.randint(0, screen.get_width())
self.y = random.randint(0, screen.get_height())
self.size = random.randint(5, 15)
self.color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
self.fall_speed = random.randint(2, 5)
def fall(self):
self.y += self.fall_speed
if self.y > self.screen.get_height():
self.y = 0 - self.size
self.x = random.randint(0, self.screen.get_width())
# 紙吹雪を順に描画する関数
def draw_confetti(screen, confetti_list):
screen.fill((255, 255, 255)) # 最初に背景を白に設定
for confetti in confetti_list:
pygame.draw.circle(screen, confetti.color, (confetti.x, confetti.y), confetti.size)
confetti.fall() # 紙吹雪を落下させる
# メイン関数
def main():
pygame.init()
screen_width, screen_height = 800, 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Wedding Confetti")
num_confettis = 100
confetti_list = [Confetti(screen) for _ in range(num_confettis)]
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 紙吹雪の描画
draw_confetti(screen, confetti_list)
# 画面の更新
pygame.display.flip()
# FPSの設定
pygame.time.Clock().tick(30)
pygame.quit()
if __name__ == "__main__":
main()
結果です。
ちょっともたついた感じにもなりますが、次で深々と降る雪を作ってみましょう。
雪のお地蔵様
今度のサンプルは横向きの動きをいれてなくて、白い雪が降ってくるというイメージですね。また、お願いしました。
若干の修正をしましたが、コードはこれです。
import pygame
import random
# 紙吹雪の設定をするためのクラス
class Confetti:
def __init__(self, screen):
self.screen = screen
self.x = random.randint(0, screen.get_width())
self.y = random.randint(0, screen.get_height())
self.size = random.randint(5, 15)
self.color = (255, 255, 255 )
self.fall_speed = random.randint(2, 5)
def fall(self):
self.y += self.fall_speed
if self.y > self.screen.get_height():
self.y = 0 - self.size
self.x = random.randint(0, self.screen.get_width()) # ... 既存のコード ...
# 紙吹雪を順に描画する関数
def draw_confetti(screen, confetti_list, jizou_img):
screen.fill((127, 127, 127)) # 最初に背景を白に設定
# お地蔵様の画像を画面の中央あたりに配置
jizou_position = (screen.get_width() // 2 - jizou_img.get_width() // 2,
screen.get_height() // 2 - jizou_img.get_height() // 2)
screen.blit(jizou_img, jizou_position)
for confetti in confetti_list:
pygame.draw.circle(screen, confetti.color, (confetti.x, confetti.y), confetti.size)
confetti.fall() # 紙吹雪を落下させる
# メイン関数
def main():
pygame.init()
screen_width, screen_height = 800, 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Wedding Confetti")
# お地蔵様の画像をロード
jizou_img = pygame.image.load('jizou.png')
num_confettis = 100
confetti_list = [Confetti(screen) for _ in range(num_confettis)]
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 紙吹雪の描画(お地蔵様の画像を含む)
draw_confetti(screen, confetti_list, jizou_img)
# 画面の更新
pygame.display.flip()
# FPSの設定
pygame.time.Clock().tick(30)
pygame.quit()
if __name__ == "__main__":
main()
結果が次のようになりました。
良い感じかなと思いますがどうでしょう。
2023/12/13
この記事が気に入ったらサポートをしてみませんか?