PythonとPygameでブロック崩しゲームを作る

## はじめに

こんにちは！今回は、PythonとPygameを使用して、シンプルなブロック崩しゲームを作成する方法を紹介します。このチュートリアルでは、基本的なゲームの仕組みを学びながら、プログラミングの楽しさを体験できます。

この記事で失敗したので、そのリベンジとしてやってみました。

https://qiita.com/Tadataka_Takahashi/items/cffc7422c7c4eac9c66f

## 目次
1. 準備
2. 要件
3. 仕様
4. ゲームの基本構造
5. コードの実装
6. コードの説明
7. 発展させるには
8. まとめ

## 準備

まず、Pygameをインストールしましょう。コマンドラインで以下のコマンドを実行します：

```
pip install pygame
```

## 要件

このプロジェクトでは、以下の要件を満たすブロック崩しゲームを作成します：

1. プレイヤーがパドルを操作してボールを打ち返せること
2. 画面上部にブロックが配置されていること
3. ボールがブロックに当たるとブロックが消えること
4. ボールが画面下部に落ちるとゲームオーバーになること（今回の実装では省略）
5. すべてのブロックを壊すとゲームクリアになること（今回の実装では省略）

## 仕様

ゲームの具体的な仕様は以下の通りです：

1. ゲーム画面
   - サイズ: 800x600 ピクセル
   - 背景色: 黒

2. パドル
   - サイズ: 幅100ピクセル、高さ20ピクセル
   - 色: 青
   - 操作: 左右矢印キーで移動
   - 速度: 5ピクセル/フレーム

3. ボール
   - サイズ: 半径10ピクセル
   - 色: 白
   - 初期位置: 画面中央
   - 初期速度: x方向 3ピクセル/フレーム、y方向 -3ピクセル/フレーム

4. ブロック
   - サイズ: 幅60ピクセル、高さ20ピクセル
   - 色: 赤
   - 配置: 5行10列、合計50個
   - 間隔: 水平5ピクセル、垂直5ピクセル

5. ゲームロジック
   - ボールが壁に当たると反射
   - ボールがパドルに当たると上向きに反射
   - ボールがブロックに当たるとブロックが消え、ボールが反射

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/89c0a94e-e9d1-aba0-8eb8-6c6f65786274.png)


6. フレームレート
   - 60 FPS (Frames Per Second)

## ゲームの基本構造

ゲームの基本構造を以下のように設計します：

1. ゲームの初期化
2. ゲームループ
   - イベント処理
   - ゲーム状態の更新
   - 画面の描画
3. ゲームの終了

```mermaid
sequenceDiagram
    participant Main Loop
    participant Event Handling
    participant Paddle Movement
    participant Ball Movement
    participant Collision Detection
    participant Rendering

    loop Game Loop
        Main Loop->>Event Handling: イベント処理
        Event Handling->>Paddle Movement: パドル移動の入力を処理
        Main Loop->>Ball Movement: ボールの位置を更新
        Main Loop->>Collision Detection: 衝突判定
        Collision Detection->>Ball Movement: ボールの方向を変更
        Collision Detection->>Main Loop: ブロックを削除
        Main Loop->>Rendering: 画面を描画
        Rendering->>Main Loop: 画面を更新
    end
```

## コードの実装

以下に、ブロック崩しゲームの基本的な実装を示します：

```python
import pygame
import sys

# 初期化
pygame.init()

# 画面設定
WIDTH = 800
HEIGHT = 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("ブロック崩し")

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

# パドルの設定
paddle_width = 100
paddle_height = 20
paddle_x = WIDTH // 2 - paddle_width // 2
paddle_y = HEIGHT - 40
paddle_speed = 5

# ボールの設定
ball_radius = 10
ball_x = WIDTH // 2
ball_y = HEIGHT // 2
ball_dx = 3
ball_dy = -3

# ブロックの設定
block_width = 60
block_height = 20
block_rows = 5
block_cols = 10
blocks = []

for row in range(block_rows):
    for col in range(block_cols):
        block = pygame.Rect(col * (block_width + 5) + 50, row * (block_height + 5) + 50, block_width, block_height)
        blocks.append(block)

# ゲームループ
clock = pygame.time.Clock()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    # パドルの移動
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT] and paddle_x > 0:
        paddle_x -= paddle_speed
    if keys[pygame.K_RIGHT] and paddle_x < WIDTH - paddle_width:
        paddle_x += paddle_speed

    # ボールの移動
    ball_x += ball_dx
    ball_y += ball_dy

    # 壁との衝突
    if ball_x <= ball_radius or ball_x >= WIDTH - ball_radius:
        ball_dx *= -1
    if ball_y <= ball_radius:
        ball_dy *= -1

    # パドルとの衝突
    if ball_y >= paddle_y - ball_radius and paddle_x < ball_x < paddle_x + paddle_width:
        ball_dy *= -1

    # ブロックとの衝突
    for block in blocks[:]:
        if block.collidepoint(ball_x, ball_y):
            blocks.remove(block)
            ball_dy *= -1
            break

    # 画面の描画
    screen.fill(BLACK)
    pygame.draw.rect(screen, BLUE, (paddle_x, paddle_y, paddle_width, paddle_height))
    pygame.draw.circle(screen, WHITE, (int(ball_x), int(ball_y)), ball_radius)
    
    for block in blocks:
        pygame.draw.rect(screen, RED, block)

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

## コードの説明

1. Pygameの初期化と画面設定を行います。
2. パドル、ボール、ブロックの初期設定を行います。
3. メインゲームループでは以下の処理を行います：
   - イベント処理（終了処理）
   - パドルの移動（左右矢印キーで制御）
   - ボールの移動と衝突判定（壁、パドル、ブロック）
   - 画面の描画（パドル、ボール、ブロック）

## 発展させるには

このコードを基に、以下のような機能を追加してゲームを発展させることができます：

- スコア表示
- ライフ制御（ボールを落とした時の処理）
- レベルデザイン（ブロックの配置パターンを変える）
- 音楽やサウンド効果の追加
- パワーアップアイテムの実装

## まとめ

今回は、PythonとPygameを使用して、基本的なブロック崩しゲームを作成しました。要件と仕様を明確にすることで、プロジェクトの目標と実装詳細を理解しやすくなりました。このコードを基に、自分なりのアイデアを加えて、オリジナルのゲームを作ってみてください。プログラミングの世界は無限の可能性に満ちています。楽しんでコーディングしましょう！