AIでプログラミング ゲーム2のコード
元記事はこれです。この記事の最後のコードをここに記してます。
このファイルをテキストで~.pyのファイルにして、pythonインストールして>python ファイル名で実行できます
import pygame
import sys
import random
# ===== 定数 =====
WIDTH, HEIGHT = 800, 600
WHITE = (255, 255, 255)
BLUE = (0, 150, 255)
RED = (255, 100, 100)
BLACK = (0, 0, 0)
GREEN = (100, 255, 100)
YELLOW = (255, 255, 100)
MAX_BALLS = 3  # 画面上のボール上限
# ===== Paddle =====
class Paddle:
    def __init__(self):
        self.width = 100
        self.height = 15
        self.rect = pygame.Rect(WIDTH//2 - self.width//2, HEIGHT - 50, self.width, self.height)
        self.speed = 7
        self.expand_time = 0
    def move(self, keys):
        if keys[pygame.K_LEFT] and self.rect.left > 0:
            self.rect.x -= self.speed
        if keys[pygame.K_RIGHT] and self.rect.right < WIDTH:
            self.rect.x += self.speed
    def expand(self):
        self.width += 40
        self.rect.width = self.width
        self.expand_time = pygame.time.get_ticks()
    def update(self):
        if self.expand_time and pygame.time.get_ticks() - self.expand_time > 5000:
            self.width = 100
            self.rect.width = self.width
            self.expand_time = 0
    def draw(self, screen):
        pygame.draw.rect(screen, BLUE, self.rect)
# ===== Ball =====
class Ball:
    def __init__(self, x=None, y=None, speed_x=4, speed_y=-4):
        self.size = 15
        self.rect = pygame.Rect(x if x else WIDTH//2, y if y else HEIGHT//2, self.size, self.size)
        self.speed_x = speed_x
        self.speed_y = speed_y
    def move(self):
        self.rect.x += self.speed_x
        self.rect.y += self.speed_y
        if self.rect.left <= 0 or self.rect.right >= WIDTH:
            self.speed_x *= -1
        if self.rect.top <= 0:
            self.speed_y *= -1
    def bounce_paddle(self, paddle):
        if self.rect.colliderect(paddle.rect):
            offset = (self.rect.centerx - paddle.rect.centerx) / (paddle.rect.width / 2)
            self.speed_x = offset * 5
            self.speed_y *= -1
    def bounce_block(self):
        self.speed_y *= -1
    def reset_position(self):
        self.rect.x = WIDTH//2
        self.rect.y = HEIGHT//2
        self.speed_x = 4
        self.speed_y = -4
    def draw(self, screen):
        pygame.draw.ellipse(screen, WHITE, self.rect)
# ===== Block =====
class Block:
    def __init__(self, x, y, w, h, block_type="normal"):
        self.rect = pygame.Rect(x, y, w, h)
        self.type = block_type  # "normal", "powerup", "multiball"
    def draw(self, screen):
        color = RED
        if self.type == "powerup":
            color = GREEN
        elif self.type == "multiball":
            color = YELLOW
        pygame.draw.rect(screen, color, self.rect)
# ===== PowerUp =====
class PowerUp:
    def __init__(self, x, y):
        self.size = 20
        self.rect = pygame.Rect(x, y, self.size, self.size)
        self.speed = 4
    def move(self):
        self.rect.y += self.speed
    def draw(self, screen):
        pygame.draw.rect(screen, GREEN, self.rect)
# ===== Game =====
class Game:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
        pygame.display.set_caption("ブロック崩し OOP版")
        self.clock = pygame.time.Clock()
        self.font = pygame.font.SysFont(None, 36)
        # 効果音・BGM
        try:
            pygame.mixer.music.load("bgm.mp3")  # 適当なBGMファイル
            pygame.mixer.music.play(-1)
            self.sound_block = pygame.mixer.Sound("block.wav")
            self.sound_powerup = pygame.mixer.Sound("powerup.wav")
            self.sound_multiball = pygame.mixer.Sound("multiball.wav")
        except:
            self.sound_block = self.sound_powerup = self.sound_multiball = None
        self.paddle = Paddle()
        self.balls = [Ball()]
        self.blocks = self.create_blocks()
        self.powerups = []
        self.score = 0
        self.lives = 3
        self.stage = 1
        self.game_over = False
    def create_blocks(self):
        blocks = []
        rows, cols = 5, 8
        block_width = WIDTH // cols
        block_height = 30
        for row in range(rows):
            for col in range(cols):
                # ランダムで特殊ブロック
                r = random.random()
                if r < 0.1:
                    btype = "powerup"
                elif r < 0.2:
                    btype = "multiball"
                else:
                    btype = "normal"
                blocks.append(Block(col * block_width, row * block_height + 50, block_width - 2, block_height - 2, btype))
        return blocks
    def reset_game(self):
        self.score = 0
        self.lives = 3
        self.stage = 1
        self.blocks = self.create_blocks()
        self.powerups.clear()
        self.paddle = Paddle()
        self.balls = [Ball()]
        self.game_over = False
    def update(self):
        keys = pygame.key.get_pressed()
        self.paddle.move(keys)
        self.paddle.update()
        for ball in self.balls[:]:
            ball.move()
            ball.bounce_paddle(self.paddle)
            # ボール落下
            if ball.rect.bottom >= HEIGHT:
                self.balls.remove(ball)
                if not self.balls:
                    self.lives -= 1
                    if self.lives > 0:
                        self.balls = [Ball()]
                        self.paddle = Paddle()
                    else:
                        self.game_over = True
                continue
            # ブロック衝突
            hit_index = ball.rect.collidelist([b.rect for b in self.blocks])
            if hit_index != -1:
                hit_block = self.blocks.pop(hit_index)
                ball.bounce_block()
                self.score += 100
                if self.sound_block: self.sound_block.play()
                if hit_block.type == "powerup":
                    self.powerups.append(PowerUp(hit_block.rect.centerx, hit_block.rect.centery))
                elif hit_block.type == "multiball":
                    if self.sound_multiball:
                        self.sound_multiball.play()
                    # 生成候補(2球)
                    spawn_candidates = [
                        Ball(hit_block.rect.centerx, hit_block.rect.centery, speed_x=4, speed_y=-4),
                        Ball(hit_block.rect.centerx, hit_block.rect.centery, speed_x=-4, speed_y=-4)
                    ]
                    # 上限を超えない分だけ追加
                    for new_ball in spawn_candidates:
                        if len(self.balls) < MAX_BALLS:
                            self.balls.append(new_ball)
        # パワーアップ処理
        for p in self.powerups[:]:
            p.move()
            if p.rect.colliderect(self.paddle.rect):
                self.paddle.expand()
                if self.sound_powerup: self.sound_powerup.play()
                self.powerups.remove(p)
            elif p.rect.top > HEIGHT:
                self.powerups.remove(p)
        # ステージクリア
        if not self.blocks:
            self.stage += 1
            for ball in self.balls:
                ball.speed_x *= 1.1
                ball.speed_y *= 1.1
            self.blocks = self.create_blocks()
            
            # クリア後はボールをパドル位置に戻す
            for ball in self.balls:
                ball.rect.centerx = self.paddle.rect.centerx
                ball.rect.bottom = self.paddle.rect.top - 1
                ball.speed_x = 4
                ball.speed_y = -4
        
    def draw(self):
        self.screen.fill(BLACK)
        self.paddle.draw(self.screen)
        for ball in self.balls:
            ball.draw(self.screen)
        for block in self.blocks:
            block.draw(self.screen)
        for p in self.powerups:
            p.draw(self.screen)
        score_text = self.font.render(f"Score: {self.score}  Stage: {self.stage}  Lives: {self.lives}", True, WHITE)
        self.screen.blit(score_text, (10, 10))
        if self.game_over:
            over_text = self.font.render("GAME OVER - Press SPACE to Restart", True, WHITE)
            self.screen.blit(over_text, (WIDTH//2 - over_text.get_width()//2, HEIGHT//2))
        pygame.display.flip()
    def run(self):
        while True:
            # ===== 1. イベント処理 =====
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                # ゲームオーバー時にスペースで再スタート
                if self.game_over and event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                    self.reset_game()
            # ===== 2. ゲーム状態更新 =====
            if not self.game_over:
                self.update()
            # ===== 3. 描画 =====
            self.draw()
            # ===== 4. フレームレート制御 =====
            self.clock.tick(60)
# ===== 実行 =====
if __name__ == "__main__":
    Game().run()
 
						