Pygameを使って RPGを作る（10. 敵の配置と衝突判定）

# 概要
配置した敵と衝突判定を行い、戦闘画面へ遷移する
遭遇した敵の名前を取得する

# Mapクラス
敵の名前とイメージパスを追加
```py
class Map(pg.sprite.Sprite):
    def __init__(self, collision_sprites, enemy_sprites):

        self.enemy_obj = [
            {
                "name": "bat",
                "path": "../img/enemy/e001.png"
            },
            {
                "name": "sneck",
                "path": "../img/enemy/e002.png"
            },
            {
                "name": "サソリ",
                "path": "../img/enemy/e003.png"
            },
        ]

        self.block_images = {
            "B" : "../maps/tree.png"
        }
        self.name = 'map_01'
        self.current_map = TILE[self.name]

        self.collision_sprites = collision_sprites
        self.enemy_sprites = enemy_sprites

        self.map_list = []
        self.enemy_list = []
        self.player = None

    def create(self):
        enemy_count = 0
        for i, row in enumerate(self.current_map):
            for j, column in enumerate(row):
                x = j * TILE_SIZE
                y = i * TILE_SIZE

                if column == 'B':
                    self.block = Block((x,y), self.block_images['B'], self.collision_sprites)
                    self.map_list.append(self.block)
                if column == 'P':
                    self.player = Player((x,y), self.collision_sprites, self.enemy_sprites)
                if column == 'E':
                    self.enemy = Enemy((x,y), self.enemy_obj[enemy_count], self.enemy_sprites)
                    enemy_count += 1
                    self.enemy_list.append(self.enemy)

        return self.player, self.map_list, self.enemy_list
```

# Playerクラス
敵衝突判定と画面遷移
```py
    def collision_enemy(self, dt, enemy_list):

        collided_enemies = []  # 衝突した敵を記録するリスト

        # 水平方向、垂直方向の衝突判定を処理
        self.hit_box_rect.x += self.direction.x * self.key_speed * dt
        self.hit_box_rect.y += self.direction.y * self.key_speed * dt

        for enemy_sprite, enemy in zip(self.enemy_sprites, enemy_list):
            if enemy_sprite.rect.colliderect(self.hit_box_rect):
                print(f'{enemy.name}と衝突しました！')
                self.game_stage = 'battle'
                self.enemy_name = enemy.name
                collided_enemies.append((enemy_sprite, enemy))

        # 衝突した敵を削除
        for enemy_sprite, enemy in collided_enemies:
            if enemy_sprite in self.enemy_sprites:
                self.enemy_sprites.remove(enemy_sprite)  # スプライトグループから削除
            if enemy in enemy_list:
                enemy_list.remove(enemy)  # インスタンスリストから削除
            # enemy.destroy()  # 敵のリソースを解放

        # メイン矩形をヒットボックスに同期
        self.rect.center = self.hit_box_rect.center
```

# Mainクラス
戦闘画面追加と画面管理情報を追加

```py
def battle_screen(self):
        pg.display.set_caption('Battle')
        self.display_surface.fill((125, 125, 0))  # 背景を赤に
        font = pg.font.SysFont("yumincho", 74)
        text = font.render(f"{self.player.enemy_name}に遭遇!", True, (255, 255, 255))
        self.display_surface.blit(text, (250, 250))

    def run(self):
        """ゲームループ"""
        dt = self.clock.tick(FPS) / 1000

        while self.running:
            # events
            self.events()
            self.game_stage = self.player.game_stage
            if self.game_stage == 'main':
                self.main_screen(dt)

            elif self.game_stage == 'battle':
                # 敵と衝突した後の画面
                self.battle_screen()
            pg.display.update()

        pg.quit()
```
# 実行結果

```terminal
$ python base_main.py 
pygame-ce 2.5.2 (SDL 2.30.8, Python 3.12.2)
batと衝突しました！
サソリと衝突しました！
sneckと衝突しました！
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576081/c39a8a79-4b9f-b425-ea00-6b71ce9d5abd.png)

遭遇した敵は削除する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576081/e5a4e8b1-512c-8052-2948-3a4cf6064374.png)