【ChatGPT×Python】プロンプトでシューティングゲームを生成する方法

【ChatGPT×Python】プロンプトでシューティングゲームを生成する方法

Amazonのアソシエイトとして、ITナレッジライフは適格販売により収入を得ています。

記事の文字数:1,580 / 総アクセス数:50 views

ChatGPTでPythonのシューティングゲームを作成する方法を紹介します。1回のプロンプトでは仕様通りとなりませんでしたが、2回目のプロンプトによる修正依頼で、想定通りのシューティングゲームを簡単に作成することができました。

ChatGPTを利用して、Pythonで動作するシューティングゲームを作成させてみました。
1回のプロンプトでは要求を満たさない結果となりましたが、2回目で修正依頼をすることで、想定通りのシューティングゲームを作成することができました。

プロンプト(1回目)

まず以下仕様で、ChatGPTにソースコード作成依頼をしました。

送信メッセージ

送信メッセージ
Pythonでシューティングゲームを作成してください。
#前提
・Python3で動作すること。
・ソースコードをコピーしてそのまま使えること。
・起動時にエラーが発生しないこと。
#仕様
・矢印キーで上下左右に実機を操作できる。
・スペースキーで弾を発射し、長押しで連射できる。
・敵に当たるか敵の弾に当たるとライフが1つ減る。
・実機のライフは3つで、0になったらゲームオーバーになる。
・実機の色は白色とする。
・敵は上から出て来て、上から下に弾を発射する。
・敵のライフは1つ。
・敵の色は赤色とする。
・敵を倒すとスコアが100増える。
・スコアは左側にSCOREと表示する。
・ライフは右側にLIFEと表示する。
・ゲームオーバー後は、Enterキーでゲームを再開できる。
#アウトプット
・上記仕様をすべて満たすソースコード
・ソースコードのファイル名
・Pythonの必要なライブラリがあれば、インストールコマンド
・作成ソースコードの起動方法
・操作方法・仕様の説明書

ChatGPT回答(1回目)

以下ChatGPTの回答です。


Pythonでシューティングゲームを作成するためには、Pygameライブラリを使用します。
以下に、仕様を満たすソースコードを提供します。

必要なライブラリ

まず、Pygameをインストールする必要があります。以下のコマンドを使用してインストールしてください。

コマンド
pip install pygame

ソースコード

次に、以下のソースコードを shooting_game.py というファイル名で保存してください。

shooting_game.pyのソースコード(クリックして展開)
shooting_game.py
import pygame
import random
# ゲームの初期化
pygame.init()
# 画面サイズの設定
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
# フォントの設定
font = pygame.font.SysFont(None, 36)
# 色の設定
white = (255, 255, 255)
red = (255, 0, 0)
black = (0, 0, 0)
# 実機クラス
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((50, 50))
self.image.fill(white)
self.rect = self.image.get_rect()
self.rect.center = (screen_width // 2, screen_height - 50)
self.speed = 5
self.lives = 3
def update(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and self.rect.left > 0:
self.rect.x -= self.speed
if keys[pygame.K_RIGHT] and self.rect.right < screen_width:
self.rect.x += self.speed
if keys[pygame.K_UP] and self.rect.top > 0:
self.rect.y -= self.speed
if keys[pygame.K_DOWN] and self.rect.bottom < screen_height:
self.rect.y += self.speed
def shoot(self):
bullet = Bullet(self.rect.centerx, self.rect.top)
all_sprites.add(bullet)
player_bullets.add(bullet)
# 弾クラス
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((5, 10))
self.image.fill(white)
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.bottom = y
self.speed = -10
def update(self):
self.rect.y += self.speed
if self.rect.bottom < 0:
self.kill()
# 敵クラス
class Enemy(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((50, 50))
self.image.fill(red)
self.rect = self.image.get_rect()
self.rect.x = random.randint(0, screen_width - self.rect.width)
self.rect.y = random.randint(-100, -40)
self.speed = random.randint(1, 3)
self.shoot_delay = random.randint(500, 1500)
self.last_shot = pygame.time.get_ticks()
def update(self):
self.rect.y += self.speed
if self.rect.top > screen_height:
self.rect.x = random.randint(0, screen_width - self.rect.width)
self.rect.y = random.randint(-100, -40)
self.speed = random.randint(1, 3)
now = pygame.time.get_ticks()
if now - self.last_shot > self.shoot_delay:
self.shoot()
self.last_shot = now
def shoot(self):
bullet = EnemyBullet(self.rect.centerx, self.rect.bottom)
all_sprites.add(bullet)
enemy_bullets.add(bullet)
# 敵の弾クラス
class EnemyBullet(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((5, 10))
self.image.fill(red)
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.top = y
self.speed = 5
def update(self):
self.rect.y += self.speed
if self.rect.top > screen_height:
self.kill()
# スプライトグループの設定
all_sprites = pygame.sprite.Group()
player_bullets = pygame.sprite.Group()
enemy_bullets = pygame.sprite.Group()
enemies = pygame.sprite.Group()
# プレイヤーの生成
player = Player()
all_sprites.add(player)
# 敵の生成
for _ in range(5):
enemy = Enemy()
all_sprites.add(enemy)
enemies.add(enemy)
# スコアとゲームオーバーフラグ
score = 0
game_over = False
# ゲームループ
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE and not game_over:
player.shoot()
if event.key == pygame.K_RETURN and game_over:
# リスタート
player.lives = 3
score = 0
game_over = False
for bullet in enemy_bullets:
bullet.kill()
for enemy in enemies:
enemy.kill()
for _ in range(5):
enemy = Enemy()
all_sprites.add(enemy)
enemies.add(enemy)
# ゲームがオーバーでない場合の処理
if not game_over:
all_sprites.update()
# プレイヤーの弾と敵の衝突判定
hits = pygame.sprite.groupcollide(enemies, player_bullets, True, True)
for hit in hits:
score += 100
enemy = Enemy()
all_sprites.add(enemy)
enemies.add(enemy)
# プレイヤーと敵の弾の衝突判定
hits = pygame.sprite.spritecollide(player, enemy_bullets, True)
for hit in hits:
player.lives -= 1
if player.lives <= 0:
game_over = True
# プレイヤーと敵の衝突判定
hits = pygame.sprite.spritecollide(player, enemies, False)
for hit in hits:
player.lives -= 1
hit.kill()
enemy = Enemy()
all_sprites.add(enemy)
enemies.add(enemy)
if player.lives <= 0:
game_over = True
# 画面の描画
screen.fill(black)
all_sprites.draw(screen)
# スコアとライフの表示
score_text = font.render(f"SCORE: {score}", True, white)
screen.blit(score_text, (10, 10))
lives_text = font.render(f"LIFE: {player.lives}", True, white)
screen.blit(lives_text, (screen_width - 150, 10))
# ゲームオーバーの表示
if game_over:
game_over_text = font.render("GAME OVER - Press Enter to Restart", True, red)
screen.blit(game_over_text, (screen_width // 4, screen_height // 2))
pygame.display.flip()
pygame.time.delay(30)
pygame.quit()

起動方法

上記のソースコードを shooting_game.py というファイル名で保存します。
コマンドラインまたはターミナルで以下のコマンドを実行してゲームを起動します。

コマンド
python shooting_game.py

操作方法・仕様の説明

  • 矢印キーで実機を上下左右に移動できます。
  • スペースキーで弾を発射できます(長押しで連射可能)。
  • 敵や敵の弾に当たるとライフが1つ減り、ライフが0になるとゲームオーバーです。
  • 敵を倒すとスコアが100増えます。
  • スコアは画面左上に SCORE として表示されます。
  • ライフは画面右上に LIFE として表示されます。
  • ゲームオーバー後はEnterキーでゲームを再開できます。
  • このコードをコピーして実行すれば、指定された仕様を満たすシューティングゲームが動作します。

動作テスト(1回目)

まず回答の指定通り、pygameをインストールしました。

pygameインストール
$ pip install pygame
Defaulting to user installation because normal site-packages is not writeable
Collecting pygame
Downloading pygame-2.6.0-cp312-cp312-win_amd64.whl.metadata (13 kB)
Downloading pygame-2.6.0-cp312-cp312-win_amd64.whl (10.8 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 10.8/10.8 MB 12.6 MB/s eta 0:00:00
Installing collected packages: pygame
Successfully installed pygame-2.6.0
[notice] A new release of pip is available: 24.0 -> 24.1.2
[notice] To update, run: C:\Users\dorae\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\python.exe -m pip install --upgrade pip

shooting_game.pyファイルを保存し、コマンドプロンプトから以下コマンドで起動します。

起動コマンド
python shooting_game.py

実行中画面

ゲームが起動しましたが、動きがもっさりとしていました。
また、弾の発射はできましたが、連射ができませんでした。

alt text

ゲームオーバー画面

ライフが0になるとゲームオーバーになり、Enterキーでリスタートできました。
こちらは想定通りの動きです。
alt text

プロンプト(2回目)

弾の連射ができないことと、動きがもっさりしていたので、以下の通り修正依頼をすることにしました。

送信メッセージ

送信メッセージ
生成ありがとうございます。確認しました。
長押しで連射できず、以下使用が満たされていませんでした。
・スペースキーで弾を発射し、長押しで連射できる。
また動きがもっさりしているので、スムーズに動作するように改善お願いします。

ChatGPT回答(2回目)

以下ChatGPTの回答です。


連射機能と動作のスムーズさを改善するために、次のようにコードを更新します。

  • 連射機能のために、弾の発射にクールダウン(発射間隔)を設定します。
  • 動作をスムーズにするために、フレームレートを管理し、更新を高速化します。

以下の修正されたソースコードを shooting_game.py にコピーして実行してください。

shooting_game.pyのソースコード(クリックして展開)
shooting_game.py
import pygame
import random
# ゲームの初期化
pygame.init()
# 画面サイズの設定
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Shooting Game")
# フォントの設定
font = pygame.font.SysFont(None, 36)
# 色の設定
white = (255, 255, 255)
red = (255, 0, 0)
black = (0, 0, 0)
# 実機クラス
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((50, 50))
self.image.fill(white)
self.rect = self.image.get_rect()
self.rect.center = (screen_width // 2, screen_height - 50)
self.speed = 5
self.lives = 3
self.shoot_delay = 250 # ミリ秒
self.last_shot = pygame.time.get_ticks()
def update(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and self.rect.left > 0:
self.rect.x -= self.speed
if keys[pygame.K_RIGHT] and self.rect.right < screen_width:
self.rect.x += self.speed
if keys[pygame.K_UP] and self.rect.top > 0:
self.rect.y -= self.speed
if keys[pygame.K_DOWN] and self.rect.bottom < screen_height:
self.rect.y += self.speed
if keys[pygame.K_SPACE]:
self.shoot()
def shoot(self):
now = pygame.time.get_ticks()
if now - self.last_shot > self.shoot_delay:
self.last_shot = now
bullet = Bullet(self.rect.centerx, self.rect.top)
all_sprites.add(bullet)
player_bullets.add(bullet)
# 弾クラス
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((5, 10))
self.image.fill(white)
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.bottom = y
self.speed = -10
def update(self):
self.rect.y += self.speed
if self.rect.bottom < 0:
self.kill()
# 敵クラス
class Enemy(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((50, 50))
self.image.fill(red)
self.rect = self.image.get_rect()
self.rect.x = random.randint(0, screen_width - self.rect.width)
self.rect.y = random.randint(-100, -40)
self.speed = random.randint(1, 3)
self.shoot_delay = random.randint(1000, 2000)
self.last_shot = pygame.time.get_ticks()
def update(self):
self.rect.y += self.speed
if self.rect.top > screen_height:
self.rect.x = random.randint(0, screen_width - self.rect.width)
self.rect.y = random.randint(-100, -40)
self.speed = random.randint(1, 3)
now = pygame.time.get_ticks()
if now - self.last_shot > self.shoot_delay:
self.shoot()
self.last_shot = now
def shoot(self):
bullet = EnemyBullet(self.rect.centerx, self.rect.bottom)
all_sprites.add(bullet)
enemy_bullets.add(bullet)
# 敵の弾クラス
class EnemyBullet(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((5, 10))
self.image.fill(red)
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.top = y
self.speed = 5
def update(self):
self.rect.y += self.speed
if self.rect.top > screen_height:
self.kill()
# スプライトグループの設定
all_sprites = pygame.sprite.Group()
player_bullets = pygame.sprite.Group()
enemy_bullets = pygame.sprite.Group()
enemies = pygame.sprite.Group()
# プレイヤーの生成
player = Player()
all_sprites.add(player)
# 敵の生成
for _ in range(5):
enemy = Enemy()
all_sprites.add(enemy)
enemies.add(enemy)
# スコアとゲームオーバーフラグ
score = 0
game_over = False
# クロックオブジェクトの生成
clock = pygame.time.Clock()
# ゲームループ
running = True
while running:
clock.tick(60) # フレームレートを60FPSに設定
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN and game_over:
# リスタート
player.lives = 3
score = 0
game_over = False
for bullet in enemy_bullets:
bullet.kill()
for enemy in enemies:
enemy.kill()
for _ in range(5):
enemy = Enemy()
all_sprites.add(enemy)
enemies.add(enemy)
# ゲームがオーバーでない場合の処理
if not game_over:
all_sprites.update()
# プレイヤーの弾と敵の衝突判定
hits = pygame.sprite.groupcollide(enemies, player_bullets, True, True)
for hit in hits:
score += 100
enemy = Enemy()
all_sprites.add(enemy)
enemies.add(enemy)
# プレイヤーと敵の弾の衝突判定
hits = pygame.sprite.spritecollide(player, enemy_bullets, True)
for hit in hits:
player.lives -= 1
if player.lives <= 0:
game_over = True
# プレイヤーと敵の衝突判定
hits = pygame.sprite.spritecollide(player, enemies, False)
for hit in hits:
player.lives -= 1
hit.kill()
enemy = Enemy()
all_sprites.add(enemy)
enemies.add(enemy)
if player.lives <= 0:
game_over = True
# 画面の描画
screen.fill(black)
all_sprites.draw(screen)
# スコアとライフの表示
score_text = font.render(f"SCORE: {score}", True, white)
screen.blit(score_text, (10, 10))
lives_text = font.render(f"LIFE: {player.lives}", True, white)
screen.blit(lives_text, (screen_width - 150, 10))
# ゲームオーバーの表示
if game_over:
game_over_text = font.render("GAME OVER - Press Enter to Restart", True, red)
screen.blit(game_over_text, (screen_width // 4, screen_height // 2))
pygame.display.flip()
pygame.quit()

この修正後のコードは、以下の改善点があります:

  • スペースキーを長押しで連射ができるようにしました。
  • クロックオブジェクトを使ってフレームレートを60FPSに設定し、動作をスムーズにしました。

これで、よりスムーズな動作と連射機能を備えたシューティングゲームを楽しむことができます。


動作テスト(2回目)

ChatGPTの回答通り、連射ができるようになり、動きもスムーズになりました!

実行中画面

alt text

ゲームオーバー画面

alt text

まとめ

  • ChatGTPでソースコードを作成する際は、具体的な仕様を記載する。
  • 記載した仕様が満たされていない場合は、修正依頼をする必要がある。

プロンプトを用いて作成依頼動作確認修正依頼のフローを繰り返してゲームの完成度を上げていくのが勧めです。
ぜひ紹介したプロンプトやソースコードをご参考にしていただけたら幸いです。

Pythonユーザにお勧めの本

人気

スッキリわかるPython入門 第2版 スッキリわかるシリーズ

難易度
実用性
読みやすさ

対話形式でスラスラ読める。複雑な概念もキャラクターが分かりやすく解説してくれます。

独習Python

難易度
実用性
網羅性

言語仕様を深く解説。なんとなく書ける状態から、自信を持って書ける状態へ引き上げてくれます。

Python1年生 第2版 体験してわかる!会話でまなべる!プログラミングのしくみ

難易度
実用性
読みやすさ

イラスト中心で、プログラミングの楽しさを教えてくれる。ワクワクしながら学べる入門書です。


以上で本記事の解説を終わります。
よいITライフを!

Pythonユーザにお勧めの本

人気

スッキリわかるPython入門 第2版 スッキリわかるシリーズ

難易度
実用性
読みやすさ

対話形式でスラスラ読める。複雑な概念もキャラクターが分かりやすく解説してくれます。

人気記事


記事を評価

Thanks!
目次
Scroll to Top