この記事では、Pythonのpygame
ライブラリを使って、古典的なゲーム「ブロック崩し」を作成する手順を解説します。ゲームの基本的な構造、オブジェクトの動かし方、衝突判定などを学びながら、一つの完成されたプログラムを構築していきます。
目次
1. 準備:Pygameの初期化と定数設定
まず、ゲームウィンドウの作成や、色、画面サイズなどの基本的な設定を行います。
import pygame
# --- Pygameの初期化 ---
pygame.init()
# --- 定数の設定 ---
# 画面サイズ
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
# 色の定義 (RGB)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
YELLOW = (255, 255, 0)
# --- ゲームウィンドウの作成 ---
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("ブロック崩し")
# --- ゲームループの制御用 ---
clock = pygame.time.Clock()
2. ゲームオブジェクトの作成
次に、ゲームに登場するパドル、ボール、ブロックを定義します。
パドルはプレイヤーが操作する長方形です。pygame.Rect
オブジェクトで表現します。
# パドルの設定
PADDLE_WIDTH = 100
PADDLE_HEIGHT = 15
paddle = pygame.Rect(
SCREEN_WIDTH // 2 - PADDLE_WIDTH // 2,
SCREEN_HEIGHT - 40,
PADDLE_WIDTH,
PADDLE_HEIGHT
)
ボールは円形で、位置(x, y座標)、半径、そして速度(x方向、y方向)の属性を持ちます。
# ボールの設定
BALL_RADIUS = 10
ball_x = SCREEN_WIDTH // 2
ball_y = SCREEN_HEIGHT // 2
ball_speed_x = 5
ball_speed_y = -5
ブロックは複数の長方形で、リストにまとめて格納します。
# ブロックの設定
BLOCK_WIDTH = 60
BLOCK_HEIGHT = 20
blocks = []
colors = [RED, YELLOW, GREEN, BLUE]
for row in range(4):
for col in range(10):
block = pygame.Rect(
col * (BLOCK_WIDTH + 10) + 70,
row * (BLOCK_HEIGHT + 10) + 50,
BLOCK_WIDTH,
BLOCK_HEIGHT
)
blocks.append({'rect': block, 'color': colors[row]})
3. ゲームのメインループ
ゲームの心臓部となるメインループを作成します。このループの中で、プレイヤーの操作、オブジェクトの移動、衝突判定、描画といったすべての処理が繰り返し行われます。
running = True
while running:
# --- 1. イベント処理 ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# --- 2. パドルの操作 ---
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and paddle.left > 0:
paddle.x -= 8
if keys[pygame.K_RIGHT] and paddle.right < SCREEN_WIDTH:
paddle.x += 8
# --- 3. ボールの移動 ---
ball_x += ball_speed_x
ball_y += ball_speed_y
# --- 4. 衝突判定 ---
# 壁との衝突
if ball_x <= BALL_RADIUS or ball_x >= SCREEN_WIDTH - BALL_RADIUS:
ball_speed_x *= -1
if ball_y <= BALL_RADIUS:
ball_speed_y *= -1
# パドルとの衝突
if paddle.collidepoint(ball_x, ball_y):
ball_speed_y *= -1
# ブロックとの衝突
for block_item in blocks:
if block_item['rect'].collidepoint(ball_x, ball_y):
blocks.remove(block_item)
ball_speed_y *= -1
break # 1フレームで壊せるブロックは1つまで
# ゲームオーバー判定 (画面下に落ちたか)
if ball_y >= SCREEN_HEIGHT - BALL_RADIUS:
# ここでゲームオーバー処理(今回はループを抜けるだけ)
running = False
# --- 5. 描画処理 ---
screen.fill(BLACK)
# パドルを描画
pygame.draw.rect(screen, WHITE, paddle)
# ボールを描画
pygame.draw.circle(screen, WHITE, (ball_x, ball_y), BALL_RADIUS)
# ブロックを描画
for block_item in blocks:
pygame.draw.rect(screen, block_item['color'], block_item['rect'])
# --- 6. 画面更新 ---
pygame.display.flip()
# --- フレームレートの設定 ---
clock.tick(60)
# --- ゲーム終了処理 ---
pygame.quit()
4. 完成したコード全体
以下に、ここまでのコードをすべてまとめた完成版を示します。
import pygame
# --- Pygameの初期化 ---
pygame.init()
# --- 定数の設定 ---
SCREEN_WIDTH, SCREEN_HEIGHT = 800, 600
BLACK, WHITE = (0, 0, 0), (255, 255, 255)
BLUE, RED, GREEN, YELLOW = (0, 0, 255), (255, 0, 0), (0, 255, 0), (255, 255, 0)
# --- ゲームウィンドウの作成 ---
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("ブロック崩し")
clock = pygame.time.Clock()
# --- パドルの設定 ---
PADDLE_WIDTH, PADDLE_HEIGHT = 100, 15
paddle = pygame.Rect(SCREEN_WIDTH // 2 - PADDLE_WIDTH // 2, SCREEN_HEIGHT - 40, PADDLE_WIDTH, PADDLE_HEIGHT)
# --- ボールの設定 ---
BALL_RADIUS = 10
ball_x, ball_y = SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2
ball_speed_x, ball_speed_y = 5, -5
# --- ブロックの設定 ---
BLOCK_WIDTH, BLOCK_HEIGHT = 60, 20
blocks = []
colors = [RED, YELLOW, GREEN, BLUE]
for row in range(4):
for col in range(10):
block = pygame.Rect(col * (BLOCK_WIDTH + 10) + 70, row * (BLOCK_HEIGHT + 10) + 50, BLOCK_WIDTH, BLOCK_HEIGHT)
blocks.append({'rect': block, 'color': colors[row]})
# --- ゲームループ ---
running = True
while running:
# イベント処理
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# パドルの操作
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and paddle.left > 0:
paddle.x -= 8
if keys[pygame.K_RIGHT] and paddle.right < SCREEN_WIDTH:
paddle.x += 8
# ボールの移動
ball_x += ball_speed_x
ball_y += ball_speed_y
# 衝突判定: 壁
if ball_x <= BALL_RADIUS or ball_x >= SCREEN_WIDTH - BALL_RADIUS:
ball_speed_x *= -1
if ball_y <= BALL_RADIUS:
ball_speed_y *= -1
# 衝突判定: パドル
if paddle.collidepoint(ball_x, ball_y) and ball_speed_y > 0:
ball_speed_y *= -1
# 衝突判定: ブロック
for block_item in blocks[:]: # リストのコピーをループする
if block_item['rect'].collidepoint(ball_x, ball_y):
blocks.remove(block_item)
ball_speed_y *= -1
break
# ゲームオーバー判定
if ball_y >= SCREEN_HEIGHT - BALL_RADIUS:
running = False
# 勝利判定
if not blocks:
running = False
# 描画
screen.fill(BLACK)
pygame.draw.rect(screen, WHITE, paddle)
pygame.draw.circle(screen, WHITE, (int(ball_x), int(ball_y)), BALL_RADIUS)
for block_item in blocks:
pygame.draw.rect(screen, block_item['color'], block_item['rect'])
# 画面更新
pygame.display.flip()
clock.tick(60)
# --- 終了処理 ---
pygame.quit()
まとめ
このチュートリアルでは、Pygameの基本的な要素(ゲームループ、イベント処理、描画、衝突判定)を使って、完全なブロック崩しゲームを作成しました。このコードをベースに、スコア機能やゲームオーバー画面、複数のステージなどを追加して、自分だけのオリジナルゲームに挑戦してみてください。