初学者がChatGPTとPythonでインベーダーゲームを作りたい①

前回はプレイヤーが存在せず、縦に箱が流れるだけのゲームになってしまったので、今回の目標としては

**1.プレイヤーを存在させる**
**2.プレイヤーの横移動を実装**
**3.敵、プレイヤー両者による攻撃
4.タイマー、スコアの表示**

### この４つの実装を目標にコードを書いてみます



```
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("インベーダーゲーム")

# 色の定義
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)

# プレイヤーの設定
player_size = 50
player_x = screen_width // 2
player_y = screen_height - 60
player_speed = 5

# 弾の設定
bullet_size = 5
bullet_speed = 7
bullets = []

# 敵の設定
invader_size = 40
invader_speed = 2
invaders = []

for x in range(0, screen_width, invader_size + 50):  # 敵の間隔を広くする
    for y in range(0, 150, invader_size + 50):  # 敵の間隔を広くする
        invaders.append(pygame.Rect(x, y, invader_size, invader_size))

# 敵の弾の設定
invader_bullets = []
invader_bullet_speed = 5
invader_shoot_interval = 1000  # 敵が弾を発射する間隔（ミリ秒）

# ゲーム関連の変数
score = 0
start_time = pygame.time.get_ticks()  # ゲーム開始時の時間
bullet_interval = 500  # プレイヤーの弾の発射間隔（ミリ秒）

# ゲームループ
running = True
clock = pygame.time.Clock()
last_bullet_time = pygame.time.get_ticks()
last_invader_shoot_time = pygame.time.get_ticks()

while running:
    screen.fill(BLACK)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # プレイヤーの動き
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT] and player_x > 0:
        player_x -= player_speed
    if keys[pygame.K_RIGHT] and player_x < screen_width - player_size:
        player_x += player_speed
    player_rect = pygame.Rect(player_x, player_y, player_size, player_size)
    pygame.draw.rect(screen, GREEN, player_rect)

    # 自動でプレイヤーの弾を発射
    current_time = pygame.time.get_ticks()
    if current_time - last_bullet_time > bullet_interval:
        bullets.append([player_x + player_size // 2, player_y])
        last_bullet_time = current_time

    # プレイヤーの弾の動き
    for bullet in bullets:
        bullet[1] -= bullet_speed
        pygame.draw.circle(screen, RED, bullet, bullet_size)
        if bullet[1] < 0:
            bullets.remove(bullet)

    # 敵の動き
    for invader in invaders:
        pygame.draw.rect(screen, RED, invader)
        invader.y += invader_speed
        if invader.y > screen_height:
            invaders.remove(invader)
            invaders.append(pygame.Rect(random.randint(0, screen_width - invader_size), 0, invader_size, invader_size))

    # 敵の弾の発射
    if current_time - last_invader_shoot_time > invader_shoot_interval:
        shooting_invader = random.choice(invaders)
        invader_bullets.append([shooting_invader.x + invader_size // 2, shooting_invader.y + invader_size])
        last_invader_shoot_time = current_time

    # 敵の弾の動き
    for bullet in invader_bullets:
        bullet[1] += invader_bullet_speed
        pygame.draw.circle(screen, BLUE, bullet, bullet_size)
        if bullet[1] > screen_height:
            invader_bullets.remove(bullet)
        if player_rect.colliderect(pygame.Rect(bullet[0] - bullet_size, bullet[1] - bullet_size, bullet_size * 2, bullet_size * 2)):
            running = False  # プレイヤーに当たったらゲームオーバー

    # プレイヤーの弾と敵の衝突判定
    for bullet in bullets:
        bullet_rect = pygame.Rect(bullet[0] - bullet_size, bullet[1] - bullet_size, bullet_size * 2, bullet_size * 2)
        for invader in invaders:
            if bullet_rect.colliderect(invader):
                bullets.remove(bullet)
                invaders.remove(invader)
                score += 1
                break

    # タイマーとスコアの表示
    elapsed_time = (pygame.time.get_ticks() - start_time) // 1000
    font = pygame.font.SysFont(None, 36)
    time_text = font.render(f"Time: {elapsed_time} sec", True, WHITE)
    score_text = font.render(f"Score: {score}", True, WHITE)
    screen.blit(time_text, (10, 10))
    screen.blit(score_text, (10, 40))

    pygame.display.flip()
    clock.tick(60)

pygame.quit()
```
タイマーやスコアの挿入にChatGPTを使用して実装、エラーの修正を行いました。

今後は、よりゲームらしくするためにドットイラストの挿入や背景の挿入を目標に進めていきます。