【Python】自作マリオのマリオを表示する

# Pygameでマリオを表示する
マリオをPythonで作成するハンズオン動画を見つけたので、実装してみる。
[参考：【#3 マリオを表示】マリオを一緒に作ってみませんか！pythonで！【ハンズオン実践解説】](https://youtu.be/UbY59EhtrLo?si=4Yxd1O5OImFB2eHn)

## **マリオを描く**
Pygameを使用して画面上にマリオを描画するための画像を作成しました。  
実際のマリオは16×16だが、今回は20×20で作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782903/fb2359ab-3945-0439-ebe3-eedb4362ff24.png)

Pygameの`Sprite`クラスを活用し、マリオのスプライト（キャラクター）を定義し、それを画面に描画する処理を実装していきます。

## **マリオのクラス定義**
```python
class Mario(pygame.sprite.Sprite): 
    ''' マリオのクラス '''
    def __init__(self): 
        pygame.sprite.Sprite.__init__(self) 
        self.image = pygame.image.load('mario001.png') 
        self.rect = pygame.Rect(150, 200, 20, 20) 
```
### **解説**
- `Mario`クラスは、Pygameの`Sprite`クラスを継承して作成されています。
- `__init__`メソッドでは、スプライトの基本的な初期化を行います。
  - `self.image = pygame.image.load('mario001.png')`  
    → `mario001.png`の画像を読み込んで、スプライトの画像として設定
  - `self.rect = pygame.Rect(150, 200, 20, 20)`  
    → 画面上の座標 `(150, 200)` に幅20px、高さ20pxの矩形を設定し、スプライトの位置とサイズを定義

## **スプライトグループの作成とマリオの追加**
```python
# スプライトグループを定義
group = pygame.sprite.RenderUpdates()

# マリオクラスを定義
mario = Mario()

# マリオをグループに追加
group.add(mario)
```
### **解説**
- `pygame.sprite.RenderUpdates()` を使ってスプライトグループを作成。  
  → スプライトグループは、複数のスプライトを一括管理するために使います。
- `mario = Mario()` で `Mario` クラスのインスタンスを作成
- `group.add(mario)` で、マリオをスプライトグループに追加  
  → これにより、グループの描画時にマリオも画面に描画されるようになります。

## **スプライトの更新と描画処理**
```python
# グループを更新
group.update()

# グループを描画
group.draw(win)
```
### **解説**
- `group.update()`  
  → スプライトグループ内の全てのスプライトを更新  
    （今回は特に`update`メソッドをオーバーライドしていないので、処理は行われません）
- `group.draw(win)`  
  → スプライトグループ内の全てのスプライトを画面に描画  
    (`win`はPygameのウィンドウオブジェクト)

# 完全なコード
```python
import pygame

# 画面サイズを定義
W, H = 320, 270

# タイル数
TILE_X = 16
TILE_Y = 14

class Mario(pygame.sprite.Sprite):
    ''' マリオのクラス
    '''
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('mario001.png')
        self.rect = pygame.Rect(150, 200, 20, 20)

def main():
    '''メイン関数'''
    # pygame初期化
    pygame.init()
    # 画面を構築
    win = pygame.display.set_mode((W, H))
    pygame.display.set_caption("Pygame Window")  # ウィンドウタイトルを設定
    # クロックを生成
    clock = pygame.time.Clock()

    # スプライトグループを定義
    group = pygame.sprite.RenderUpdates()
    # マリオクラスを定義
    mario = Mario()
    # マリオをグループに追加
    group.add(mario)


    # 背景色の初期値（黒）
    bg_color = (0, 0, 0)

    # イベントループ
    running = True
    while running:
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                running = False  # ループを抜ける
            
        # 背景を塗りつぶす
        win.fill((135, 206, 235))

        # グループを更新
        group.update()

        # グループを描画
        group.draw(win)

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

        clock.tick(30)  # FPS制限 (60FPS)

    pygame.quit()

# Pythonのファイルが直接実行された場合のみmain()を実行
if __name__ == '__main__':
    main()

```

## **まとめ**
このコードによって、以下の動作が実現できます：
1. `mario001.png` の画像を読み込んでスプライト化
2. `RenderUpdates()` を使いスプライトグループに追加
3. `update()` でスプライトの更新
4. `draw(win)` でスプライトを描画
5. ループ処理で、ウィンドウが閉じられるまでマリオが表示され続ける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782903/84860dd5-32a7-3258-56a7-1a9082f68093.png)