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()