Pygameを使って RPGを作る（8. Map作成 Sprite版）

# 概要
Spriteの場合、事前にSpriteグループを登録し、クラスのインスタンス作成時に引き渡すことで、プログラムがすっきりする

# メインクラス

```py
# グループのインスタンス
self.collision_sprites = pg.sprite.Group()

# Mapクラスに登録する
self.map_list = Map(self.collision_sprites).create()

# Mapクラスで作成したものをそのまま、Playerクラスに引き渡す
# Playerクラスのインスタンス宣言
self.player = Player([250,100],self.collision_sprites)

# 中略

# player Update
self.player.update(dt) #引数で指定していた、Blockクラスのインスタンスを引き渡す必要がなくなる

```
# Playerクラス

```py 
class Player(pg.sprite.Sprite):
    
    def __init__(self, pos, collision_sprites):
        super().__init__()
        # 衝突判定用Spriteを引き受ける
        self.collision_sprites = collision_sprites
```

内部のメンバー変数で処理できてしまうので、隠蔽できる
```py
def collision(self,dt):
        """ブロックとの衝突判定と位置調整を行う"""
        # 水平方向の衝突処理
        self.hit_box_rect.x += self.direction.x * self.key_speed *dt
        for block in self.collision_sprites:
            if block.rect.colliderect(self.hit_box_rect):
                print(f"Horizontal Collision detected: {self.hit_box_rect}, {block.rect}")
                if self.direction.x > 0:  # 右に移動中
                    self.hit_box_rect.right = block.rect.left
                elif self.direction.x < 0:  # 左に移動中
                    self.hit_box_rect.left = block.rect.right
                # 衝突後、移動量をリセット
                self.direction.x = 0

        # 垂直方向の衝突処理
        self.hit_box_rect.y += self.direction.y * self.key_speed *dt
        for block in self.collision_sprites:
            if block.rect.colliderect(self.hit_box_rect):
                print(f"Vertical Collision detected: {self.hit_box_rect}, {block.rect}")
                if self.direction.y > 0:  # 下に移動中
                    self.hit_box_rect.bottom = block.rect.top
                elif self.direction.y < 0:  # 上に移動中
                    self.hit_box_rect.top = block.rect.bottom
                # 衝突後、移動量をリセット
                self.direction.y = 0

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

Playerと同様引数でSpriteを引き受ける
```py 
class Block(pg.sprite.Sprite):
    def __init__(self, pos, img_path, collision_sprites):
        super().__init__(collision_sprites)

        # イメージの読み込み
        self.img_path = img_path
        self.surface = pg.image.load(self.img_path).convert_alpha()
        # 位置
        self.pos = pos
        # rect
        self.rect = self.surface.get_frect(topleft=pos)
```

# Mapクラス
Playerと同様引数でSpriteを引き受けて、そのまま、Blockクラスに引き渡す
```py
class Map(pg.sprite.Sprite):
    def __init__(self, collision_sprites):

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

        self.collision_sprites = collision_sprites

        self.map_list = []

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

                if column == key:
                    self.block = Block((x,y), self.block_images[key], self.collision_sprites)
                    self.map_list.append(self.block)

        return self.map_list
```

# まとめ

1. メインクラスでSpriteグループを作成
1. メインクラスからSpriteグループをMapクラスに引き渡す
1. MapクラスからSpriteグループをBlockクラスに引き渡す
1. メインクラスからSpriteグループをPlayerクラスに引き渡す

結果：
Spriteグループがメインクラス、Mapクラス、Blockクラス、Playerクラスで共有される

※MapクラスでPlayerを配置する予定なので、MapクラスからPlayerクラスにSpriteを引き渡すことになるので、今後メインクラスからPlayerクラスにSpriteを渡す導線がなくなる