生成AIでプログラミング 二歩目です
経緯
生成AIでプログラミング はじめの一歩|ふーみん (note.com)
でステージの背景を作り、一つの赤い四角のオブジェクトを配置しました。次はこれを動かしてみます。
オブジェクトを動かす
キー入力で左右に動かす
キー入力で動かすコードをおねがいしたら次のコードを作ってくれました。
import pygame
import sys
# 初期化
pygame.init()
# ウィンドウのサイズ
width, height = 600, 600
# ウィンドウの作成
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("左右に動かすスプライト")
# Sprite クラスの定義
class MySprite(pygame.sprite.Sprite):
def __init__(self, color, width, height):
super().__init__()
self.image = pygame.Surface((width, height))
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.center = (width // 2, height // 2) # 初期位置
def update(self, keys):
# キー入力に応じてスプライトを動かす
if keys[pygame.K_LEFT]:
self.rect.x -= 5
if keys[pygame.K_RIGHT]:
self.rect.x += 5
# スプライトの生成
sprite = MySprite((255, 0, 0), 50, 50)
# グループにスプライトを追加
all_sprites.add(sprite)
# ゲームループ
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# キー入力を取得
keys = pygame.key.get_pressed()
# スプライトの更新
all_sprites.update(keys)
# 画面をクリア
screen.fill((255, 255, 255))
# グループ内の全てのスプライトを描画
all_sprites.draw(screen)
# 画面を更新
pygame.display.flip()
# フレームレートを制限
clock.tick(60)
結果は次にしめします
ダブルクリックしてください。
うごきもちょっとぎこちないですが、実際の動きはもっとスムースです。
スプライト(オブジェクト)の生成
コードを見てみると動かすために次のようなコードが付け加えられています。
まず、スプライト(オブジェクト)の定義ですが、その中に動かし方を記述していますね。
# Sprite クラスの定義
class MySprite(pygame.sprite.Sprite):
def __init__(self, color, width, height):
super().__init__()
self.image = pygame.Surface((width, height))
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.center = (width // 2, height // 2) # 初期位置
def update(self, keys):
# キー入力に応じてスプライトを動かす
if keys[pygame.K_LEFT]:
self.rect.x -= 5
if keys[pygame.K_RIGHT]:
self.rect.x += 5
def __init__(self, color, width, height):
で静的な定義を表し、
def update(self, keys):
で動的な定義で、動かし方を示しています。
これに続いて次で具体的に一つのスプライト(インスタンス)が生成されます。
# スプライトの生成
sprite = MySprite((255, 0, 0), 50, 50)
グループの生成
このスプライトを直接使うのではなく、グループに取り入れて扱うようである。プログラムの簡素化ができるのだろうか。
クラスというのを新しく定義するのでなく、直接、つぎでグループ(インスタンス)を定義している。
# グループの作成
all_sprites = pygame.sprite.Group()
次にスプライトをこのグループに紐付けしている。グループのメンバーとする。
これで、直接、スプライトを扱わずに、グループを扱うようになる。これはゲーム・ループの中でつぎのようになる。
ゲームの更新
ゲームループもそれに応じて変更が必要です。次が加わります。
# キー入力を取得
keys = pygame.key.get_pressed()
# スプライトの更新
all_sprites.update(keys)
# 画面をクリア
screen.fill((255, 255, 255))
# グループ内の全てのスプライトを描画
all_sprites.draw(screen)
# 画面を更新
pygame.display.flip()
# フレームレートを制限
clock.tick(60)
キー入力があるということ、グループ・スプライトの更新ですね。ここでkeysというのが引数として使われていますね。画面をクリアは基本でありましたね。描画はグループインスタンスの描画となります。画面を更新は基本でありましたね。最後に動きがあるということでフレームレートも毎回更新しているのですね。
まとめ
今回は短いですが、ここまでとしておきます。次回はちょっとしたゲームをやりたいと思います。
興味を持っていただいて、ありがとうございました。
補足01
Scratchの作品
孫が小2の時に作ったScratchの最初の作品です。
このような作品がどういう形でできるかを教えてもらいました。
図形を動かす
絵を直接動かすのではなく、まずは図形を動かしました。いろいろとトラブルはあったのですが、コードはつぎのようになっています。
import pygame
import sys
# 初期化
pygame.init()
# ウィンドウのサイズ
width, height = 800, 600
# ウィンドウの作成
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("動物たちのアニメーション")
# グループの作成
all_sprites = pygame.sprite.Group()
# Sprite クラスの定義
class AnimalSprite(pygame.sprite.Sprite):
def __init__(self, color, shape, width, height, x, y):
super().__init__()
self.image = pygame.Surface((width, height), pygame.SRCALPHA)
pygame.draw.polygon(self.image, color, shape)
self.rect = self.image.get_rect()
self.rect.topleft = (x, y) # 初期位置を設定
self.direction = 1 # 1: 右に移動, -1: 左に移動
def update(self):
# スプライトを左右に動かす
self.rect.x += 5 * self.direction
# 画面の端に到達したら反転
if self.rect.right > width:
self.direction = -1
elif self.rect.left < 0:
self.direction = 1
# 各動物の形状を定義
red_square = [(255, 0, 0), [(0, 0), (50, 0), (50, 50), (0, 50)], 50, 50]
#green_circle = [(0, 255, 0), [(25, 25)], 50, 50]
green_circle = [(0, 255, 0), [(0, 0), (50, 0), (50, 50), (0, 50)], 50, 50]
blue_triangle = [(0, 0, 255), [(25, 0), (50, 50), (0, 50)], 50, 50]
yellow_star = [(255, 255, 0), [(25, 0), (30, 30), (50, 40), (30, 50), (25, 80), (20, 50), (0, 40), (20, 30)], 50, 80]
# 動物のスプライトを生成してグループに追加
all_sprites.add(AnimalSprite(*red_square, x=50, y=50))
all_sprites.add(AnimalSprite(*green_circle, x=150, y=100))
all_sprites.add(AnimalSprite(*blue_triangle, x=250, y=150))
all_sprites.add(AnimalSprite(*yellow_star, x=350, y=200))
# ゲームループ
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# スプライトの更新
all_sprites.update()
# 画面をクリア
screen.fill((255, 255, 255))
# グループ内の全てのスプライトを描画
all_sprites.draw(screen)
# 画面を更新
pygame.display.flip()
# フレームレートを制限
clock.tick(60)
各動物の形状を定義はつぎのようになっています。
red_square = [(255, 0, 0), [(0, 0), (50, 0), (50, 50), (0, 50)], 50, 50]
#green_circle = [(0, 255, 0), [(25, 25)], 50, 50]
green_circle = [(0, 255, 0), [(0, 0), (50, 0), (50, 50), (0, 50)], 50, 50]
blue_triangle = [(0, 0, 255), [(25, 0), (50, 50), (0, 50)], 50, 50]
yellow_star = [(255, 255, 0), [(25, 0), (30, 30), (50, 40), (30, 50), (25, 80), (20, 50), (0, 40), (20, 30)], 50, 80]
なぜか、green_circle で円を描くつもりですが、うまく描けず、red_squareの定義を使いました。
動物・背景を入れる
Scratchから動物の絵をダウンロードし、背景は前の絵を使いました。
import pygame
import sys
import os
# 初期化
pygame.init()
# ウィンドウのサイズ
width, height = 600, 600
# ウィンドウの作成
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("画像を使ったアニメーション")
background_image = pygame.image.load("background.jpg")
background_rect = background_image.get_rect()
# グループの作成
all_sprites = pygame.sprite.Group()
# Sprite クラスの定義
class AnimalSprite(pygame.sprite.Sprite):
def __init__(self, image_path, x, y, scale=0.5): # デフォルト引数を最後に移動
super().__init__()
original_image = pygame.image.load(image_path).convert_alpha()
self.image = pygame.transform.scale(original_image, (int(original_image.get_width() * scale), int(original_image.get_height() * scale)))
self.rect = self.image.get_rect()
self.rect.center = (x, y) # 初期位置に設定
self.direction = 1 # 1: 右に移動, -1: 左に移動
def update(self):
# スプライトを左右に動かす
self.rect.x += 5 * self.direction
# 画面の端に到達したら反転
if self.rect.right > width:
self.direction = -1
elif self.rect.left < 0:
self.direction = 1
# 動物の画像ファイルパスを定義
bear = os.path.join(os.path.dirname(__file__), "bear.svg")
cat = os.path.join(os.path.dirname(__file__), "cat.svg")
fox = os.path.join(os.path.dirname(__file__), "fox.svg")
Griffin = os.path.join(os.path.dirname(__file__), "Griffin.svg")
# 動物のスプライトを生成してグループに追加
all_sprites.add(AnimalSprite(bear, x=width//2, y=height//2 -100, scale=0.5))
all_sprites.add(AnimalSprite(cat, x=width//2, y=height//2 - 200, scale=0.5))
all_sprites.add(AnimalSprite(fox, x=width//2, y=height//2 + 200, scale=0.5))
all_sprites.add(AnimalSprite(Griffin, x=width//2, y=height//2 + 100, scale=0.5))
# ゲームループ
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# スプライトの更新
all_sprites.update()
# 画面をクリア
screen.fill((255, 255, 255))
# 背景画像を描画
screen.blit(background_image, background_rect)
# グループ内の全てのスプライトを描画
all_sprites.draw(screen)
# 画面を更新
pygame.display.flip()
# フレームレートを制限
clock.tick(60)
sprite の定義はつぎのようになっています
def __init__(self, image_path, x, y, scale=0.5): # デフォルト引数を最後に移動
super().__init__()
original_image = pygame.image.load(image_path).convert_alpha()
self.image = pygame.transform.scale(original_image, (int(original_image.get_width() * scale), int(original_image.get_height() * scale)))
self.rect = self.image.get_rect()
self.rect.center = (x, y) # 初期位置に設定
self.direction = 1 # 1: 右に移動, -1: 左に移動
決まり文句として覚える必要もないのでしょう。
部分的なコードを聞いて、それを組み込もうと思っていましたが、簡単なコードだからか、いつも全体のコードを示してくれます。とりあえずは構造だけは気にしておこうかと思います。
# 動物の画像ファイルパスを定義
bear = os.path.join(os.path.dirname(__file__), "bear.svg")
cat = os.path.join(os.path.dirname(__file__), "cat.svg")
fox = os.path.join(os.path.dirname(__file__), "fox.svg")
Griffin = os.path.join(os.path.dirname(__file__), "Griffin.svg")
# 動物のスプライトを生成してグループに追加
all_sprites.add(AnimalSprite(bear, x=width//2, y=height//2 -100, scale=0.5))
all_sprites.add(AnimalSprite(cat, x=width//2, y=height//2 - 200, scale=0.5))
all_sprites.add(AnimalSprite(fox, x=width//2, y=height//2 + 200, scale=0.5))
all_sprites.add(AnimalSprite(Griffin, x=width//2, y=height//2 + 100, scale=0.5))
画像を定義して、グループに入れます。
動画としてはあれこれいじらないといけませんが、とりあえず、ScratchのSpriteがそのまま、SVGで入れることが出来ました。
2023/11/23
この記事が気に入ったらサポートをしてみませんか?