Pygameでモグラたたきゲームを作る

こんにちは！

この記事では、PythonとPygameを使って、モグラたたきゲームを作ります。
開発環境は、macOSを前提としてます。

### 1. 環境構築

最初に、ゲーム開発に必要な環境を構築しましょう。

**準備:**

- **Python**
[https://www.python.org/](https://www.python.org/) からダウンロードしてインストールします。
　
- **仮想環境（venv）**
開発用のディレクトリで以下のコマンドを実行し、Pythonの仮想環境を作ります。
例えば、今回の作業ディレクトリを `mole_game`とした場合、以下のようになります。

```bash
mkdir mole_game
cd mole_game
python -m venv venv
source venv/bin/activate
```
仮想環境のアクティベートに成功すると、ターミナルが以下のようになります。
```bash
(venv) MacBook-XXX:mole_game myname$ 
```

- **Pygame**
Pythonでゲームを作るためのライブラリです。
ターミナルで以下のコマンドを実行してインストールします。

```bash
pip install pygame
```

 - **モグラとハンマーの画像**
今回は、いつも個人開発でお世話になってる [ICOOON MONO](https://icooon-mono.com/) さんから、ギャングのアイコンと猫の手のアイコンを利用しました。

[ギャングのアイコン](https://icooon-mono.com/10669-%e3%82%ae%e3%83%a3%e3%83%b3%e3%82%b0%e3%81%ae%e3%82%a2%e3%82%a4%e3%82%b3%e3%83%b3/)
32px, rgb(210, 101, 58) に設定しました。

[猫の手のアイコン](https://icooon-mono.com/15974-%e7%8c%ab%e3%81%ae%e6%89%8b%e3%81%ae%e3%83%95%e3%83%aa%e3%83%bc%e7%b4%a0%e6%9d%901/)
48px, rgb(4, 150, 222) に設定しました。

これらの画像は、ソースコード（mole_game.py）と同じ場所に置いてください。


### 2. 完成イメージ
先に完成イメージを貼っておきます。
簡易的な画面なので少し分かりにくいですが、5*5のマスがあり、どこか1つからモグラが出現するようにしました。
猫の手でバシバシ叩きます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/ef4e7a28-a27d-6953-284e-e32596a4122d.png" width="90%" />


### 3. ゲームのソースコード

```python:mole_game.py
import pygame
import random
import time

# 画面のサイズ
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 400

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

# モグラのクラス
class Mole:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.visible = False
        self.appear_time = 0

    def appear(self):
        self.visible = True
        self.appear_time = time.time()

    def disappear(self):
        self.visible = False

    def draw(self, screen):
        if self.visible:
            screen.blit(MOLE_IMAGE, (self.x, self.y))

# ハンマーのクラス
class Hammer:
    def __init__(self):
        self.x = SCREEN_WIDTH // 2
        self.y = SCREEN_HEIGHT // 2

    def update(self, mouse_x, mouse_y):
        self.x = mouse_x
        self.y = mouse_y

    def draw(self, screen):
        screen.blit(HAMMER_IMAGE, (self.x, self.y))

# ゲームのメインループ
def main():
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption("モグラたたきゲーム")

    # 画像の読み込み
    global MOLE_IMAGE, HAMMER_IMAGE, FONT
    MOLE_IMAGE = pygame.image.load("mole.png").convert_alpha()
    HAMMER_IMAGE = pygame.image.load("cat.png").convert_alpha()

    # フォントの設定
    FONT = pygame.font.Font(None, 36)

    # モグラのリスト
    moles = [
        Mole(i * 60 + 20, j * 60 + 20) for i in range(5) for j in range(5)
    ]

    # ハンマー
    hammer = Hammer()

    # スコア
    score = 0

    # タイマー
    start_time = time.time()
    game_time = 30

    # ゲームループ
    running = True
    while running:
        # イベント処理
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.MOUSEBUTTONDOWN:
                for mole in moles:
                    if mole.visible and mole.x < event.pos[0] < mole.x + MOLE_IMAGE.get_width() and mole.y < event.pos[1] < mole.y + MOLE_IMAGE.get_height():
                        mole.disappear()
                        score += 100

        # モグラをランダムに出現させる
        # 25個の穴からランダムに1つを選択
        mole_index = random.randint(0, len(moles) - 1)
        moles[mole_index].appear()

        # モグラを消す
        for mole in moles:
            if mole.visible and time.time() - mole.appear_time > 1:
                mole.disappear()

        # ハンマーの更新
        mouse_x, mouse_y = pygame.mouse.get_pos()
        hammer.update(mouse_x, mouse_y)

        # 画面の描画
        screen.fill(BLACK)

        # モグラを描画
        for mole in moles:
            mole.draw(screen)

        # ハンマーを描画
        hammer.draw(screen)

        # スコアの描画
        score_text = FONT.render(f"Score: {score}", True, WHITE)
        screen.blit(score_text, (10, 10))

        # 残り時間の描画
        elapsed_time = time.time() - start_time
        time_left = game_time - elapsed_time
        time_text = FONT.render(f"Time: {int(time_left)}", True, WHITE)
        screen.blit(time_text, (10, 50))

        # 画面を更新
        pygame.display.flip()

        # ゲーム時間終了
        if elapsed_time > game_time:
            running = False

        # 1秒間待機
        time.sleep(1)

    # ゲーム終了処理
    pygame.quit()

# メイン関数を実行
if __name__ == "__main__":
    main()
```

### 4. 実行

上記のコードを `mole_game.py` ファイルに保存し、ターミナルで以下のコマンドを実行してゲームを実行します。

```bash
python mole_game.py
```

### 5. まとめ

この記事では、PythonとPygameを使って、モグラたたきゲームを制作する方法を解説しました。
みなさんもチャレンジしてみてください！

**今後の改善予定:**

- モグラの種類を増やす
- モグラの出現パターンを変更する
- スコアに応じて難易度を変更する
- ゲームオーバー画面を追加する