pygameでRPG（早い順）


[新RPGの目次](https://qiita.com/hijpa/items/31900e327315fa8e4eea)　

# 簡易コード（早い順）

<details><summary>ここをクリックしてください</summary>

```python:

import pygame

# 画面の初期化
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption("数値順に処理実行")
white = (255, 255, 255)

# 処理データ 
process_data = sorted([
    {"type": "num1", "value": 70},
    {"type": "num2", "value": 90},
], key=lambda item: item["value"], reverse=True)

execute_index = 0
a = 0
b = 0
clock = pygame.time.Clock()
running = True
while running:
    clock.tick(60)
    screen.fill(white)  
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_z:
                if execute_index < len(process_data):
                    item = process_data[execute_index]
                    if item["type"] == "num1":
                        a += 1
                    elif item["type"] == "num2":
                        b += 1
                    execute_index += 1
                    print(a, b)
                    if execute_index == len(process_data):
                        execute_index = 0
    pygame.display.update()
pygame.quit()


```

---

### **`sorted()` の説明**
```python
process_data = sorted([
    {"type": "num1", "value": 70},
    {"type": "num2", "value": 90},
], key=lambda item: item["value"], reverse=True)
```
✅ `sorted()` は **リストをソートするPythonの組み込み関数**  
✅ `key` → ソート基準を指定するオプション引数  
✅ `reverse` → `True` にすると降順（デフォルトは `False` で昇順）  
✅ `sorted()` は **元のリストを変更せず、新しいソート済みリストを返す**

---

### **`lambda` の説明**
```python
key=lambda item: item["value"]
```
✅ `lambda`（ラムダ式）は **「無名関数」** を作るための記述方法  
✅ 通常の `def` を使った関数と違い、**関数名をつけずに1行で簡潔に記述** できる  
✅ **関数の構文：**
```python
lambda 引数: 戻り値
```
✅ **`def` を使った場合**
```python
def get_value(item):
    return item["value"]
```
✅ **`lambda` を使った場合**
```python
lambda item: item["value"]
```

このコードでは：
- **引数** → `item`（辞書）
- **戻り値** → `item["value"]`（辞書の `"value"` の値）

つまり、リストの各要素（辞書）に対して `"value"` の値を取得し、それを基準に並び替えます。

process_data = [
    {"type": "num2", "value": 90},
    {"type": "num1", "value": 70},
]


---

```python
if execute_index < len(process_data):
    item = process_data[execute_index]
    if item["type"] == "num1":
        a += 1
    elif item["type"] == "num2":
        b += 1
    execute_index += 1
    print(a, b)
    if execute_index == len(process_data):
        execute_index = 0
```

このコードは `process_data` というリストを順番に処理し、`type` に応じて変数 `a` と `b` の値を増加させる処理を行っています。  

---

### **🔹 コードの動作**
このコードの目的は **`process_data` の要素を順番に処理し、対応する変数 (`a` または `b`) を更新する** ことです。

---

### **🔹 1. `execute_index` のチェック**
```python
if execute_index < len(process_data):
```
✅ **`execute_index`（現在の処理位置）が `process_data` の長さより小さいかチェック**  
→ `process_data` の範囲内なら処理を実行

---

### **🔹 2. 現在の処理データを取得**
```python
item = process_data[execute_index]
```
✅ **`process_data` の `execute_index` 番目の要素を `item` に代入**  
→ `item` は辞書型データ（例：`{"type": "num1", "value": 70}`）

---

### **🔹 3. `type` に応じた処理**
```python
if item["type"] == "num1":
    a += 1
elif item["type"] == "num2":
    b += 1
```
✅ **`item["type"]` の値に応じて `a` または `b` を増加**
- `"num1"` の場合 → `a` を増やす
- `"num2"` の場合 → `b` を増やす

---

### **🔹 4. `execute_index` を進める**
```python
execute_index += 1
```
✅ **`execute_index` を 1 増やし、次のデータを処理できるようにする**

---

### **🔹 5. 結果を表示**
```python
print(a, b)
```
✅ **現在の `a` と `b` の値を表示**  
→ コンソール上で更新された値を確認可能

---

### **🔹 6. `execute_index` のリセット**
```python
if execute_index == len(process_data):
    execute_index = 0
```
✅ **`execute_index` がリストの末尾に達したら `0` にリセット**  
→ データの繰り返し処理が可能になる（ループ内で何度でも処理を実行できる）

---

### **🔹 処理の流れ（例）**
もし `process_data` が以下のようなリストだった場合：
```python
process_data = [
    {"type": "num2", "value": 90},
    {"type": "num1", "value": 70},
]
```
**実行の流れは以下のようになります**（`Z`キーが押されたと仮定）：
1. `execute_index = 0` → `num2` の処理 → `b += 1` → `print(a, b)` → 結果: `0 1`
2. `execute_index = 1` → `num1` の処理 → `a += 1` → `print(a, b)` → 結果: `1 1`
3. `execute_index = 2` → `execute_index` をリセット → 次回キー押下時、最初から処理

---

## **🔹 まとめ**
✅ **リスト `process_data` のデータを順番に処理**
✅ **各データの `"type"` に応じて `a` または `b` を増加**
✅ **末尾まで処理したら `execute_index` をリセットし、繰り返し可能にする**

このコードは **「Zキーを押すごとにデータを順番に処理し、カウントを更新する」** という動作をします！  



</details>

# 戦闘画面（早い順）


<details><summary>ここをクリックしてください</summary>


```python:


import pygame
from pygame import *
import sys
import random

# テキストを改行して描画する関数
def draw_text(surface, message, pos, font, color=(255, 255, 255)):
    lines = message.split('\n')
    x, y = pos
    for line in lines:
        text_surface = font.render(line, True, color)
        surface.blit(text_surface, (x, y))
        y += text_surface.get_height() + 9

# セットアップ
pygame.init()
width, height = 640, 480
screen=pygame.display.set_mode((width, height))
pygame.display.set_caption('battle')

# 色
white = (255,255,255)
black = (0,0,0)

# ここにフォントのパスを貼り付ける
font = pygame.font.Font(, 18)
# ここにカーソル画像のパスを貼り付ける
cursor = pygame.image.load()
# SE
# ここにボタン音のパスを貼り付ける
sound = pygame.mixer.Sound()


# 初期ステータス
Max_HP = 53
player_HP = 53
Max_MP = 0
player_MP = 0
Level = 1
player_quick = 4

actor_index = 0

# モンスター
nameA = "スライム"
nameB = "ウルフ"
nameC = "バード"
groupA = "ウルフ"
groupB = "スライム　ウルフ"
groupC = "ウルフ　スライム　バード"
monster_list = [groupA,groupB,groupC]
mon = random.choice(monster_list)
mon_group_list = mon.split()
mon_quickness_dict = {nameA:2,nameB:5,nameC:6}
status_data = [{"type": "player", "quickness": player_quick,"name": "ゆうしゃ"}]

for i in range(len(mon_group_list)):  
    status_data.append({
        "quickness": mon_quickness_dict[mon_group_list[i]],
        "name": f"{mon_group_list[i]}",
    })


# ゲームの状態管理

phase = 0 # 戦闘の段階を管理
battle_message = True
command = False
select = False

# バトルメッセージ
message = "モンスターが　あらわれた！"
# レンダリング
text_player = font.render("ゆうしゃ", True, white)
text_H = font.render("H", True, white)
text_M = font.render("M", True, white)
text_abbr = font.render("ゆ：　", True, white)
text_attack = font.render("こうげき", True, white)
text_monster = font.render("モンスター", True, white)

# カーソル
cursor_x = 30
cursor_y = 368
alpha = 220 # 透明度
delta = 5   # 透明度の増減

clock = pygame.time.Clock()
running = True

# ゲームのメインループ
while running:
    clock.tick(60)
    # 画面を黒色に塗りつぶし
    screen.fill((0, 0, 0))

    # ステータスウィンドゥ
    # 白いヨコ線
    pygame.draw.line(screen, white, (20, 58),(118, 58))
    # ステータスウィンドゥの枠
    pygame.draw.rect(screen, white, (20, 20, 102, 134), 3, 5)
    screen.blit(text_player,(35, 35))
    screen.blit(text_H,(35, 65))
    text_HP = font.render(f"{player_HP}", True, white)
    screen.blit(text_HP,(85, 65))
    screen.blit(text_M,(35, 95))
    text_MP = font.render(f"{player_MP}", True, white)
    screen.blit(text_MP,(85, 95))
    screen.blit(text_abbr,(35, 125))
    text_Lv = font.render(f"{Level}", True, white)
    screen.blit(text_Lv,(85, 125))

    # メッセージウィンドゥ
    if battle_message:
        # バトルメッセージの枠
        pygame.draw.rect(screen, white, Rect(20, 320, 600, 140), 3, 5)
        # バトルメッセージ
        draw_text(screen,message,(40,350),font)
    # コマンドウィンドゥ
    if command:
        # カーソル
        screen.blit(cursor, (cursor_x, cursor_y))
        cursor.set_alpha(alpha)
        alpha += delta
        if alpha <= 120 or alpha >= 255:
            delta = -delta
        # 白いヨコ線
        pygame.draw.line(screen, white, (20, 358),(236, 358))
        # コマンドウィンドゥの枠
        pygame.draw.rect(screen, white, (20, 320, 220, 140), 3, 5)
        screen.blit(text_player,(80, 335))
        screen.blit(text_attack,(50, 370))
        # 魔物選択ウィンドゥ
        if select:
            # 魔物選択ウィンドゥの枠
            pygame.draw.rect(screen, white, (245, 320, 220, 140), 3, 5)
            screen.blit(text_monster,(290, 330))


    pygame.display.update()
    # キーハンドラー
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_z:
                # あらわれた！を消してコマンドウィンドゥをひらく
                if phase == 0:
                    sound.play()                        
                    battle_message = False # あらわれた！を消す
                    command = True
                    phase = 1
                # コマンドウィンドゥを開いたまま、魔物選択ウィンドゥをひらく
                elif phase == 1:
                    sound.play()                        
                    select = True
                    cursor_x = 270
                    cursor_y = 328
                    phase = 2
                # 魔物選択ウィンドゥを消して、メッセージの表示
                elif phase == 2:
                    command = False
                    select = False
                    battle_message = True
                    phase = 3
                    status_data2 = sorted(status_data, key=lambda dictionary: dictionary["quickness"], reverse=True)
                    if actor_index < len(status_data2):
                        current_actor = status_data2[actor_index]
                        sound.play()
                        message = f'{current_actor["name"]}の　こうげき！'
                        phase = 3

                    elif actor_index == len(status_data2):
                        actor_index = 0
                        sound.play()
                        battle_message, command = False, True
                        phase, cursor_x, cursor_y = 1, 30, 368

                elif phase == 3:
                    sound.play()
                    message += "\nモンスターに　～のダメージ！" if current_actor["name"] == "ゆうしゃ" else "\nゆうしゃに　～のダメージ！"
                    actor_index += 1
                    phase = 2


```


  
</details>

# コードと変数の説明


<details><summary>ここをクリックしてください</summary>

コード概要
1.インポート

2.関数
　(テキスト改行)

3.セットアップ
　(色、パス、初期ステータス、**モンスター関連**、ゲーム状態の管理、バトルメッセージ、
 レンダリング、カーソル)

4.メインループ
　(ステータスウィンドゥの描画、メッセージウィンドゥの描画、コマンドウィンドゥの描画、
　魔物選択ウィンドゥの描画)

5.キーハンドラー
　（Zキー：　あらわれた！を消す → コマンドウィンドゥ → 魔物選択ウィンドゥ
 　　　　　　→ **メッセージ**）



---

### **変数の説明（整理後）**

#### **基本的なステータス**
- `player_quick` → **勇者の素早さ**（行動順に影響）

#### **行動管理**
- `actor_index` → **現在の行動者の指標**
  - 初期値は `0`
  - **最大値** = 勇者 + モンスターの数 - `1`
  - **行動ごとに `+1`**
  - **ターン終了時に `0` にリセット**

#### **モンスター関連**
- `nameA, nameB, nameC` → **モンスターの名前**
- `groupA, groupB, groupC` → **各モンスターのグループ**
- `monster_list` → **すべてのモンスターグループが入ったリスト**
- `mon` → **monster_list からランダムに選ばれたモンスターグループ（文字列）**
- `mon_group_list` → **mon（文字列）をリスト化したもの**
- `mon_quickness_dict` → **モンスターの素早さを格納した辞書**

#### **ステータス管理**
- `status_data` → **勇者とモンスターの素早さ・名前が入った辞書のリスト**
- `status_data2` → **status_data を素早さが高い順に並び替えたもの**
- `current_actor` → **status_data2 から actor_index に対応する辞書（現在の行動者）**

---


### **コードの説明**

#### **1. モンスターグループのリスト作成**
```python
monster_list = [groupA, groupB, groupC]
# 実際のデータ例: ["ウルフ", "スライム ウルフ", "ウルフ スライム バード"]
```
- `monster_list` は **全てのモンスターのグループを格納したリスト**。  
- 各要素は **モンスターの組み合わせを示す文字列** になっている。  

#### **2. ランダムにモンスターグループを選択**
```python
mon = random.choice(monster_list)
# 例: "スライム ウルフ"
```
- `random.choice(monster_list)` で **ランダムなモンスターグループを取得**。  
- `mon` は **選ばれたグループ（文字列）**。  

#### **3. モンスターグループを個別に分割**
```python
mon_group_list = mon.split()
# 例: ["スライム", "ウルフ"]
```
- `.split()` を使い、**選ばれたモンスターグループ（文字列）をリスト化**。  
- `mon_group_list` は **個々のモンスター名を含むリスト** になる。  

#### **4. 各モンスターのステータス情報をリストに追加**
```python
for i in range(len(mon_group_list)):  
    status_data.append({
        "quickness": mon_quickness_dict[mon_group_list[i]],  # 素早さを取得
        "name": f"{mon_group_list[i]}",  # 名前を取得
    })
```
- `mon_group_list` の各モンスターについて処理を行う。  
- `mon_quickness_dict` から **対応するモンスターの素早さを取得**。  
- 各モンスターの **名前と素早さを辞書にして `status_data` に追加**。  

#### **5. `status_data` の例（リストの内容）**
```python
status_data = [
    {"quickness": 4, "name": "ゆうしゃ"},
    {"quickness": 2, "name": "スライム"},
    {"quickness": 5, "name": "ウルフ"}
]
```
- `status_data` は **勇者とモンスターの名前と素早さを格納した辞書のリスト**。  
- 行動順の判定などに使用できる。  

---

</details>