Pygameを使って RPGを作る（7. Map作成 Spriteなし版）

# 概要
Mapを作成し、PlayerをMap内に配置する。
とりあえず、PlayerはMap内から出れないようにする

# Mapデータ

```py
TILE_SIZE = 64
TILE = {
    "map_01": [
        'BBBBBBBBBBBBBBBBBBB',
        'B.................B',
        'B.................B',
        'B.................B',
        'B.................B',
        'B.....BBBB........B',
        'B.................B',
        'B.................B',
        'BBBBBBBBBBBBBBBBBBB',
    ],
    }
```
# Mapクラス

```py 
class Map:
    def __init__(self):
        self.block_images = {
            "B" : "../maps/tree.png"
        }
        self.name = 'map_01'
        self.current_map = TILE[self.name]

        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.map_list.append(self.block)
        return self.map_list
```
このコードは、`Map` クラスの一部で、`create` メソッドを使って、ゲーム内で表示されるブロック（障害物など）を配置する処理を行っています。コードの流れを解説します。

---

### **`Map` クラスの構成**

1. **`__init__` メソッド**  
   - `self.block_images`  
     ここでは、ブロックの種類とその画像ファイルのパスを管理する辞書を定義しています。この辞書には `"B"` というキーがあり、`"B"` に対応する値は `"../maps/tree.png"` という画像パスです。これは、`tree.png` という画像をブロックの画像として使うということです。
     
   - `self.name`  
     マップの名前を `'map_01'` に設定しています。これにより、どのマップを使用するかが指定されます。

   - `self.current_map`  
     `TILE` 辞書から、`self.name` に基づいてマップデータを取得しています。`TILE[self.name]` の部分では、`TILE` という辞書から `'map_01'` に対応するマップデータを取得します。このマップデータは通常、二次元リストであり、マップのタイル（セル）情報が格納されています。

   - `self.map_list`  
     空のリストを初期化しており、このリストは後で作成したブロックを保持します。

---

2. **`create` メソッド**  
   このメソッドは、マップを実際に作成する役割を持っています。コードの流れを順番に説明します。

   - `key = 'B'`  
     この行で、マップ内で `"B"` という記号がブロック（木など）を表すことを示しています。例えば、`TILE[self.name]` に `"B"` が含まれているセルがブロックになるというルールです。

   - **二重ループ（`for`）**  
     ```python
     for i, row in enumerate(self.current_map):
         for j, column in enumerate(row):
     ```
     - 外側のループは、マップの行（縦方向）を処理します。`enumerate(self.current_map)` により、`i` が行番号、`row` がその行のデータになります。
     - 内側のループは、各行内の列（横方向）を処理します。`enumerate(row)` により、`j` が列番号、`column` がそのセルの内容になります。

   - **座標計算**  
     ```python
     x = j * TILE_SIZE
     y = i * TILE_SIZE
     ```
     各セルの位置を計算しています。`TILE_SIZE` は、タイルの一辺のサイズを示す定数で、`x` と `y` はセルの左上の座標になります。

   - **ブロックの配置**  
     ```python
     if column == key:
         self.block = Block((x, y), self.block_images[key])
         self.map_list.append(self.block)
     ```
     - もし現在のセル (`column`) が `"B"`（ブロックを表す）であれば、`Block` クラスのインスタンスを作成し、その位置を `(x, y)` として指定します。
     - `self.block_images[key]` で `"B"` に対応する画像パス（`"../maps/tree.png"`）を取得し、ブロックにその画像を割り当てます。
     - 作成したブロックを `self.map_list` に追加します。

   - 最後に、`self.map_list` を返すことで、作成したすべてのブロックがリストとして返されます。

---

### **まとめ**
- `Map` クラスは、マップデータをもとにブロック（例えば木や岩など）を生成するクラスです。
- `create` メソッドは、マップのタイル情報をもとに各タイルをブロックとして作成し、リストに格納します。
- `"B"` という記号を使ってブロックを表現し、その位置と画像を指定してゲーム内に配置します。

このコードは、ゲームのマップを動的に生成するための処理の一部として機能しています。

# Mainクラスの部分
MapクラスでBlockのインスタンスリストを返却し、メインクラスで描画と衝突判定を行う。
※メインクラスからBlockクラスを直接呼ばない。

```py
# Map
self.map_list = Map().create()

#中略

 # 衝突用ブロック
for map in self.map_list:
    self.display_surface.blit(map.surface, map.rect)

# playerの表示    
self.display_surface.blit(self.player.surface,self.player.rect)

# player Update
self.player.update(dt, self.map_list) 
```
ゲーム画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576081/52020b67-8aa7-8646-1994-3e1a70a10284.png)

Spriteをつかった動画が多いが、なくても、実現できているので、とりあえずよしとする。