Pythonでのゲーム開発に興味があるなら、Pygameライブラリは素晴らしいスタートポイントです。Pygameは2Dゲームの開発をシンプルにするための強力なライブラリで、Pythonを使ってグラフィックスや音声の処理、ユーザー入力の管理が簡単にできます。この記事では、Pygameを使ってシンプルな2Dゲームを作るための基礎を学びます。
Pygameの主要機能
| 機能 | 説明 | 主なモジュール |
|---|---|---|
| ウィンドウ管理 | ゲーム画面の作成・更新 | pygame.display |
| 描画 | 図形・画像の描画 | pygame.draw, pygame.image |
| イベント処理 | キーボード・マウス入力 | pygame.event, pygame.key |
| 音声 | BGM・効果音の再生 | pygame.mixer |
| 時間管理 | FPS制御・タイマー | pygame.time |
| 衝突判定 | オブジェクト間の当たり判定 | pygame.Rect |
Pygameのインストール
まず、Pygameライブラリをインストールする必要があります。
pip install pygame
インストールの確認をします。
import pygame
print(pygame.version.ver) # バージョン番号が表示されれば成功
Pygameの基本構造
Pygameでゲームを作る際の基本的な流れは、以下のステップに分かれます。
1. 初期化(pygame.init())
↓
2. ウィンドウの作成(pygame.display.set_mode())
↓
3. メインループ開始
├── イベント処理(キーボード・マウス)
├── ゲーム状態の更新
├── 画面の描画
└── 画面の更新(pygame.display.flip())
↓
4. 終了処理(pygame.quit())
基本的なウィンドウの作成
以下は、Pygameでゲームウィンドウを作成する最も基本的なコードです。
import pygame
import sys
# Pygameの初期化
pygame.init()
# 画面サイズの定数
WIDTH, HEIGHT = 800, 600
# ウィンドウの作成
screen = pygame.display.set_mode((WIDTH, HEIGHT))
# ウィンドウタイトルを設定
pygame.display.set_caption("Pygame入門")
# FPSを制御するためのClockオブジェクト
clock = pygame.time.Clock()
# メインループ
running = True
while running:
# イベント処理
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 背景色を設定(RGB: 白)
screen.fill((255, 255, 255))
# 画面の更新
pygame.display.flip()
# 60FPSに制限
clock.tick(60)
# 終了処理
pygame.quit()
sys.exit()
FPS制御の重要性
pygame.time.Clock()を使うことで、ゲームの動作速度を一定に保てます。
clock = pygame.time.Clock()
while running:
# ... ゲーム処理 ...
# 60FPSに制限(1秒間に60回ループ)
clock.tick(60)
# 実際のFPSを取得
actual_fps = clock.get_fps()
キャラクターの描画
次に、シンプルなキャラクターを描画してみましょう。
import pygame
import sys
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("キャラクター描画")
clock = pygame.time.Clock()
# 色の定義(RGB)
WHITE = (255, 255, 255)
BLUE = (0, 128, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
# プレイヤーの設定
player_pos = [100, 100]
player_size = 50
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 背景を白で塗りつぶし
screen.fill(WHITE)
# 四角形を描画(プレイヤー)
pygame.draw.rect(screen, BLUE, (*player_pos, player_size, player_size))
# 円を描画
pygame.draw.circle(screen, RED, (300, 200), 30)
# 線を描画
pygame.draw.line(screen, GREEN, (400, 100), (500, 200), 3)
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
主な描画関数
| 関数 | 説明 | 引数 |
|---|---|---|
pygame.draw.rect() | 四角形 | surface, color, rect |
pygame.draw.circle() | 円 | surface, color, center, radius |
pygame.draw.line() | 線 | surface, color, start, end, width |
pygame.draw.polygon() | 多角形 | surface, color, points |
キャラクターの移動
キーボード入力に応じてキャラクターを移動させます。
import pygame
import sys
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("キャラクター移動")
clock = pygame.time.Clock()
WHITE = (255, 255, 255)
BLUE = (0, 128, 255)
# プレイヤーの設定
player_x = WIDTH // 2
player_y = HEIGHT // 2
player_size = 50
player_speed = 5
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# ESCキーで終了
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
# キーの状態を取得
keys = pygame.key.get_pressed()
# 矢印キーまたはWASDキーで移動
if keys[pygame.K_LEFT] or keys[pygame.K_a]:
player_x -= player_speed
if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
player_x += player_speed
if keys[pygame.K_UP] or keys[pygame.K_w]:
player_y -= player_speed
if keys[pygame.K_DOWN] or keys[pygame.K_s]:
player_y += player_speed
# 画面外に出ないように制限(境界チェック)
player_x = max(0, min(player_x, WIDTH - player_size))
player_y = max(0, min(player_y, HEIGHT - player_size))
# 描画
screen.fill(WHITE)
pygame.draw.rect(screen, BLUE, (player_x, player_y, player_size, player_size))
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
キーボード入力の2つの方法
# 方法1: pygame.key.get_pressed() - 押しっぱなしを検出
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
print("スペースキーが押されている")
# 方法2: イベントで検出 - 押した瞬間・離した瞬間を検出
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
print("スペースキーが押された")
if event.type == pygame.KEYUP:
if event.key == pygame.K_SPACE:
print("スペースキーが離された")
衝突判定(コリジョン検出)
ゲームでは、オブジェクト同士が接触したかどうかを判定する必要があります。
import pygame
import sys
import random
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("衝突判定")
clock = pygame.time.Clock()
WHITE = (255, 255, 255)
BLUE = (0, 128, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
# プレイヤー(Rectオブジェクトを使用)
player = pygame.Rect(100, 100, 50, 50)
player_speed = 5
# アイテム
item = pygame.Rect(
random.randint(0, WIDTH - 30),
random.randint(0, HEIGHT - 30),
30, 30
)
# スコア
score = 0
font = pygame.font.Font(None, 36)
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]:
player.x -= player_speed
if keys[pygame.K_RIGHT]:
player.x += player_speed
if keys[pygame.K_UP]:
player.y -= player_speed
if keys[pygame.K_DOWN]:
player.y += player_speed
# 境界チェック
player.clamp_ip(screen.get_rect())
# 衝突判定
if player.colliderect(item):
score += 1
# アイテムを新しい位置に移動
item.x = random.randint(0, WIDTH - item.width)
item.y = random.randint(0, HEIGHT - item.height)
# 描画
screen.fill(WHITE)
pygame.draw.rect(screen, BLUE, player)
pygame.draw.rect(screen, RED, item)
# スコア表示
score_text = font.render(f"Score: {score}", True, (0, 0, 0))
screen.blit(score_text, (10, 10))
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
Rectの便利なメソッド
rect = pygame.Rect(x, y, width, height)
# 衝突判定
rect.colliderect(other_rect) # 矩形同士の衝突
rect.collidepoint(x, y) # 点との衝突
# 位置の取得・設定
rect.center # 中心座標
rect.topleft # 左上座標
rect.bottomright # 右下座標
# 境界内に収める
rect.clamp_ip(screen.get_rect())
画像の読み込みと表示
実際のゲームでは、画像ファイルを使用します。
import pygame
import sys
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
# 画像の読み込み
try:
player_image = pygame.image.load("player.png").convert_alpha()
# 画像のサイズ変更
player_image = pygame.transform.scale(player_image, (64, 64))
except pygame.error:
# 画像がない場合はサーフェスを作成
player_image = pygame.Surface((64, 64))
player_image.fill((0, 128, 255))
player_rect = player_image.get_rect()
player_rect.center = (WIDTH // 2, HEIGHT // 2)
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]:
player_rect.x -= 5
if keys[pygame.K_RIGHT]:
player_rect.x += 5
screen.fill((255, 255, 255))
screen.blit(player_image, player_rect) # 画像を描画
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
サウンドの再生
BGMや効果音を追加すると、ゲームの雰囲気が向上します。
import pygame
import sys
pygame.init()
pygame.mixer.init() # サウンドシステムの初期化
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
# サウンドの読み込み
try:
# 効果音
jump_sound = pygame.mixer.Sound("jump.wav")
jump_sound.set_volume(0.5) # 音量を50%に設定
# BGM
pygame.mixer.music.load("bgm.mp3")
pygame.mixer.music.set_volume(0.3)
pygame.mixer.music.play(-1) # -1でループ再生
except pygame.error as e:
print(f"サウンドファイルの読み込みに失敗: {e}")
jump_sound = None
player_y = 400
is_jumping = False
velocity_y = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE and not is_jumping:
is_jumping = True
velocity_y = -15
if jump_sound:
jump_sound.play()
# ジャンプ処理
if is_jumping:
player_y += velocity_y
velocity_y += 0.8 # 重力
if player_y >= 400:
player_y = 400
is_jumping = False
velocity_y = 0
screen.fill((135, 206, 235)) # 空色
pygame.draw.rect(screen, (0, 128, 255), (100, player_y, 50, 50))
pygame.draw.rect(screen, (100, 200, 100), (0, 450, WIDTH, 150)) # 地面
pygame.display.flip()
clock.tick(60)
pygame.mixer.music.stop()
pygame.quit()
sys.exit()
ゲームの拡張アイデア
基本的なPygameの使い方が理解できたら、次のような機能を追加してみましょう。
| 機能 | 説明 |
|---|---|
| 敵キャラクター | プレイヤーを追いかける敵を実装 |
| スコアシステム | ハイスコアの保存・読み込み |
| ゲームオーバー | 残機システム、ゲームオーバー画面 |
| メニュー画面 | タイトル画面、ポーズ機能 |
| アニメーション | スプライトシートを使った歩行アニメーション |
完成版:シンプルなゲーム
これまでの要素を組み合わせた完成版のコードです。
import pygame
import sys
import random
# 初期化
pygame.init()
# 定数
WIDTH, HEIGHT = 800, 600
FPS = 60
# 色
WHITE = (255, 255, 255)
BLUE = (0, 128, 255)
RED = (255, 0, 0)
BLACK = (0, 0, 0)
# ゲームクラス
class Game:
def __init__(self):
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Pygameサンプルゲーム")
self.clock = pygame.time.Clock()
self.font = pygame.font.Font(None, 36)
self.reset()
def reset(self):
self.player = pygame.Rect(WIDTH // 2, HEIGHT // 2, 50, 50)
self.items = [self.spawn_item() for _ in range(5)]
self.score = 0
self.running = True
def spawn_item(self):
return pygame.Rect(
random.randint(0, WIDTH - 20),
random.randint(0, HEIGHT - 20),
20, 20
)
def handle_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
self.running = False
if event.key == pygame.K_r:
self.reset()
def update(self):
keys = pygame.key.get_pressed()
speed = 5
if keys[pygame.K_LEFT] or keys[pygame.K_a]:
self.player.x -= speed
if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
self.player.x += speed
if keys[pygame.K_UP] or keys[pygame.K_w]:
self.player.y -= speed
if keys[pygame.K_DOWN] or keys[pygame.K_s]:
self.player.y += speed
self.player.clamp_ip(self.screen.get_rect())
# アイテム収集
for item in self.items[:]:
if self.player.colliderect(item):
self.items.remove(item)
self.items.append(self.spawn_item())
self.score += 10
def draw(self):
self.screen.fill(WHITE)
pygame.draw.rect(self.screen, BLUE, self.player)
for item in self.items:
pygame.draw.rect(self.screen, RED, item)
score_text = self.font.render(f"Score: {self.score}", True, BLACK)
self.screen.blit(score_text, (10, 10))
pygame.display.flip()
def run(self):
while self.running:
self.handle_events()
self.update()
self.draw()
self.clock.tick(FPS)
pygame.quit()
sys.exit()
# ゲーム実行
if __name__ == "__main__":
game = Game()
game.run()
まとめ
Pygameは Pythonで簡単に2Dゲームを作るための素晴らしいツールです。今回学んだ内容をまとめます。
| 項目 | 内容 |
|---|---|
| 初期化 | pygame.init() |
| ウィンドウ | pygame.display.set_mode() |
| 描画 | pygame.draw.rect(), screen.blit() |
| 入力 | pygame.key.get_pressed() |
| 衝突判定 | rect.colliderect() |
| FPS制御 | pygame.time.Clock().tick(60) |
まずは基本を押さえ、徐々に機能を追加して、自分だけのゲームを作ってみましょう!