見出し画像

生成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


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