0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

pygameでRPG(戦闘画面:そうび 全体攻撃)

Last updated at Posted at 2025-06-25

新RPGの目次

Xキーでキャンセル


import pygame
from pygame import *
import sys
import time
import random
from decimal import Decimal, getcontext
from decimal import Decimal, ROUND_DOWN


# 部分一致で値を取得する関数
def get_value_by_partial_key(dictionary, partial_key):
    for key in dictionary:
        if key in partial_key:
            return dictionary[key]
    return None

# 改行してテキストを描画する関数(バトルメッセージ)
def draw_text(surface, lines, pos, font, color=(255, 255, 255)):
    x, y = pos
    for i, line in enumerate(lines):
        if i <= 3:
            text_surface = font.render(line, True, color)
            surface.blit(text_surface, (x, y))
            y += int(text_surface.get_height() * 1.5)

# 2列×3行のテキストを描画する関数(ステータスウィンドウ・コマンドウィンドゥ)
def draw_text_grid(screen, text_list, start_x, start_y, spacing_x, spacing_y, font, white):
    for col_index, col in enumerate(text_list):  # 列ごとに処理
        for row_index, text in enumerate(col):  # 各行のテキストを描画
            text_surface = font.render(text, True, white)
            x = start_x + col_index * spacing_x  # 列ごとにX座標を調整
            y = start_y + row_index * spacing_y  # 行ごとにY座標を調整
            screen.blit(text_surface, (x, y))

# ここのpathはそのままにしておく(パスを貼り付けるところではない)
def bgm(path):
    pygame.mixer.music.load(path)
    pygame.mixer.music.play(-1)

def status_window(data):
    pygame.draw.line(screen, white, (data["x"], 58), (data["x"] + 98, 58))  # 横線
    pygame.draw.rect(screen, white, (data["x"], 20, 102, 134), 3, 5)  # 枠線
    
    text = font.render(data["name"], True, white)
    screen.blit(text, (data["x"] + 15, 35))  # 名前を表示
    
    # ステータスの表示
    text_list2 = [["H", "M", f"{data['first_letter']}"], [f"{data['HP']}", f"{data['MP']}", f"{data['level']}"]]
    draw_text_grid(screen, text_list2, start_x=data["x"] + 10, start_y=65, spacing_x=40, spacing_y=30, font=font, white = white)            

# ステータス計算関数
def calc_power(strength, weapon):
    return strength + weapon_data[weapon]

def calc_defence(strength, helmet, shield, armor):
    return strength + helmet_data[helmet] + shield_data[shield] + armor_data[armor]

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

# ここにフォントのパスを貼り付ける
font = pygame.font.Font(, 18)
# ここにカーソル画像のパスを貼り付ける
cursor = pygame.image.load()
# ここにモンスター画像のパスを貼り付ける
monsterA_image = pygame.image.load()
# ここにモンスター画像のパスを貼り付ける
monsterB_image = pygame.image.load()
# ここにモンスター画像のパスを貼り付ける
monsterC_image = pygame.image.load()

# SE
# ここにボタン音のパスを貼り付ける
sound = pygame.mixer.Sound()
# ここにダメージ音のパスを貼り付ける
sound2 = pygame.mixer.Sound()
# ここにレベルアップのパスを貼り付ける
sound3 = pygame.mixer.Sound()

# BGM
# ここに戦闘のBGMのパスを貼り付ける
battle_bgm = 
# ここに勝ったときのBGMのパスを貼り付ける
win_bgm = 
# ここに負けたときのBGMのパスを貼り付ける
lose_bgm = 

bgm(battle_bgm)    

# モンスター
nameA = ""
nameB = ""
nameC = ""
# モンスターのグループ
# 全角スペースで区切ります
# ex) "スライム ウルフ"
# ひとグループ5体までです
groupA = ""
groupB = ""
groupC = ""
monster_list = [groupA,groupB,groupC]


# キャラの名前
player_nameA = "ゆうしゃ"
player_nameB = "せんし"
player_nameC = "まどうし"
player_nameD = "そうりょ"


# 色
white = (255, 255, 255)

# カーソル
alpha = 220
delta = 5

lines = ["モンスターが あらわれた!"]
text_up = False
text_up_num = 0


battle_message = True
command = False
mon_select = False
masic_select = False
defeat = False
item_select = False
equip_select = False

# 戦闘準備の終了フラグ
all_select = False
# player_dataをstatus_dataに1回だけ追加するため(ターン数を数える)
turn_num = 1
# インデックス
actor_index = 0
mon_select_index = 0
masic_index = 0
chara_index = 0
item_index = 0
cmd_index = 0
cmd_num1 = 0
cmd_num2 = 0
equip_index = 0
# コマンド入力の順番
cmd_chara_index = 0

# フェーズ
phase = 0
masic_phase = 0
item_phase = 0

# 枠点滅
status_flash = 0
status_visible = 0
mon_flash = 0
mon_visible = 0
player_damage = 0
mon_damage = 0

# ミス、強烈な一撃
random_value= 0
critical = 1

# 全体攻撃
is_all_attack = False

# まほうエフェクト
masic_effect = 0
# まほうフレーム
masic_frame = 0
# まほうサーフェイス
damera_surface = pygame.Surface((width,height),SRCALPHA)
damera_surface.fill((255,201,14,128))
hoimun_surface = pygame.Surface((width,height),SRCALPHA)
hoimun_surface.fill((255,255,255,128))
# まほうリスト
damera = {"masic_name":"ダメラ","MP":2,"数値":10,"masic_effect":1,"masic_type":"攻撃まほう","surface":damera_surface}
hoimun = {"masic_name":"ホイムン","MP":3,"数値":30,"masic_effect":2,"masic_type":"補助まほう","surface":hoimun_surface}
masic_list = [damera,hoimun]
cmd_cursor = False
# キャラリスト
chara_group_list = [player_nameA,player_nameB,player_nameC,player_nameD]
# アイテムリスト
# _item = {"item_name":"","item_type":"アイテム","item_effect":,"数値":}
item_list = ["せいすい", "やくそう", "げんきのかけら", "まほうのしずく", "ひかりのたま"]
item_data = {"やくそう":{"item_effect":2,"item_parameter":30}}
item_effect = 0

# 武具データ
weapon_data = {"なし": 0, "きのぼう": 5, "つるぎ": 7, "オノ": 9, "ブーメラン": 23}
helmet_data = {"なし": 0, "ぼうし": 2}
shield_data = {"なし": 0, "きのたて": 2, "てつのたて": 5}
armor_data = {"なし": 0, "ぬののふく": 3, "たびのふく": 5, "よろい": 7}

equip_effect_data = {"ブーメラン": "全体攻撃"}
equip_effect = 0

# アイテム種別に応じた処理
equip_categories = {
    "weapon": weapon_data,
    "helmet": helmet_data,
    "shield": shield_data,
    "armor": armor_data,
}
current_item = item_list[item_index]

# レクト
select_rect = pygame.Rect(width * 0.4,height * 0.67,220,140)
select_rectx,select_recty = select_rect.topleft
cmd_rect = pygame.Rect(20, height * 0.67, 220, 140)
cmd_rectx,cmd_recty = cmd_rect.topleft
message_rect = pygame.Rect(20, height * 0.67, 600, 140)
message_rectx,message_recty = message_rect.topleft

# 2列×3行のテキストデータ
text_list = [
    ["攻撃", "魔法", "ガード"],  # 1列目
    ["アイテム", "装備", "逃げる"]  # 2列目
]

status_data = []
player_data = []
equip_data = [{},{},{},{}]
# 勇者の初期ステータス
#player_name_dict = {chara_group_list[0]:,chara_group_list[1]:}
player_Max_HP_dict = {player_nameA:15, player_nameB:17,player_nameC:8,player_nameD:9}
player_HP_dict = {player_nameA:15, player_nameB:17,player_nameC:8,player_nameD:9}
player_Max_MP_dict = {player_nameA:6,player_nameB:0,player_nameC:9,player_nameD:8}
player_MP_dict = {player_nameA:6,player_nameB:0,player_nameC:9,player_nameD:8}
player_strength_dict = {player_nameA:8,player_nameB:10,player_nameC:2,player_nameD:4}
player_quick_dict = {player_nameA:6,player_nameB:2,player_nameC:4,player_nameD:5}
player_tough_dict = {player_nameA:2,player_nameB:6,player_nameC:3,player_nameD:2}
player_level_dict = {player_nameA:1,player_nameB:1,player_nameC:1,player_nameD:1}
player_first_letter_dict = {player_nameA:chara_group_list[0][0:1], player_nameB:chara_group_list[1][0:1],player_nameC:chara_group_list[2][0:1],player_nameD:chara_group_list[3][0:1]}
EXP_dict = {player_nameA:0, player_nameB:0,player_nameC:0,player_nameD:0}
status_x_dict = {player_nameA:20, player_nameB:140,player_nameC:260,player_nameD:380}
player_masic_dict = {player_nameA:[hoimun,damera],player_nameB:[],player_nameC:[damera],player_nameD:[hoimun]}
player_item_dict = {player_nameA:["やくそう","げんきのかけら", "まほうのしずく", "ひかりのたま"],
                    player_nameB:["やくそう"],
                    player_nameC:["やくそう","せいすい", "まほうのしずく"],
                    player_nameD:["やくそう","まほうのしずく"]}
player_equip_dict = {player_nameA:[" きのぼう", " ブーメラン", " たびのふく"],
                    player_nameB:[" きのぼう", " オノ", " よろい"],
                    player_nameC:[" きのぼう", " ぼうし", " ぬののふく"],
                    player_nameD:[" きのぼう",  " ぬののふく"]}
player_E_dict = {player_nameA:["", "E", "E"],
                    player_nameB:["E", "", "E"],
                    player_nameC:["E", "E", "E"],
                    player_nameD:["E",  "E"]}

for i in range(len(chara_group_list)):
    equip_data[i].update({
        "weapon_name": "なし",
        "helmet_name": "なし",
        "shield_name": "なし",
        "armor_name": "なし"
    })
    for j, E in enumerate(player_E_dict[chara_group_list[i]]):
        if E == "E":
            for category, data_dict in equip_categories.items():
                if player_equip_dict[chara_group_list[i]][j][1:] in data_dict:
                    # 装備する
                    if category == "weapon":
                        equip_data[i].update({
                        "weapon_name": player_equip_dict[chara_group_list[i]][j][1:]
                            })
                    elif category == "helmet":
                        equip_data[i].update({
                        "helmet_name": player_equip_dict[chara_group_list[i]][j][1:]
                            })
                    elif category == "shield":
                        equip_data[i].update({
                        "shield_name": player_equip_dict[chara_group_list[i]][j][1:]
                            })
                    elif category == "armor":
                        equip_data[i].update({
                        "armor_name": player_equip_dict[chara_group_list[i]][j][1:]
                            })
            
for i in range(len(chara_group_list)):  
    player_data.append({
        "type": "player",
        "num": i,
        "name": f"{chara_group_list[i]}",
        "Max_HP": player_Max_HP_dict[chara_group_list[i]],
        "HP": player_HP_dict[chara_group_list[i]],
        "Max_MP": player_Max_MP_dict[chara_group_list[i]],
        "MP":player_MP_dict[chara_group_list[i]],
        "strength": player_strength_dict[chara_group_list[i]],
        "power": calc_power(player_strength_dict[chara_group_list[i]], equip_data[i]["weapon_name"]),
        "tough": player_tough_dict[chara_group_list[i]],
        "defence": calc_defence(player_tough_dict[chara_group_list[i]], equip_data[i]["helmet_name"], equip_data[i]["shield_name"], equip_data[i]["armor_name"]),
        "quickness": player_quick_dict[chara_group_list[i]],
        "level": player_level_dict[chara_group_list[i]],
        "first_letter": player_first_letter_dict[chara_group_list[i]],
        "x":status_x_dict[chara_group_list[i]],
        "masic_list":player_masic_dict[chara_group_list[i]],
        "item_list":player_item_dict[chara_group_list[i]],
        "equip_list":player_equip_dict[chara_group_list[i]],
        "E_list":player_E_dict[chara_group_list[i]],
        "item_effect":0,
        "equip_effect":0,
        "cmd_index":0,
        "masic_index":0,
        "mon_select_index":0,
        "item_index":0,
        "equip_index":0,
        "chara_index":0,
        "attack_on":0
    })

# レベルアップ
level_up_list = {player_nameA: [7, 23,47,110,220,50,800,1300,2000,2900,4000,5500],
                 player_nameB: [7,23,47,110,220,50,800,1300,2000,2900,4000,5500],
                 player_nameC: [7,23,47,110,220,50,800,1300,2000,2900,4000,5500],
                 player_nameD: [7,23,47,110,220,50,800,1300,2000,2900,4000,5500]}
level_up_index = {player_nameA: 0, player_nameB: 0,player_nameC:0,player_nameD:0}
# レベルアップに足りるEXPがあるか判定する順番
level_up_chara_num = 0
hit_and_miss = [0,1]
Gold = 0

# ステータスアップの種類
status_names = ["ちから", "すばやさ", "まもり", "最大HP", "最大MP"]
# ステータスの名称を辞書player_dataのキーに置き換えるための辞書
status_names_dict = {"ちから":"strength","すばやさ":"quickness","まもり":"defence","最大HP":"Max_HP","最大MP":"Max_MP"}
# ステータス上昇値のリスト
status_up_list = []


# モンスターの初期ステータス
mon_images_dict = {nameA: monsterA_image,
                   nameB: monsterB_image,
                   nameC: monsterC_image}
mon_HP_dict = {nameA: 8,nameB: 9,nameC: 40}
mon_strength_dict = {nameA: 9,nameB: 10,nameC: 12}
mon_defence_dict = {nameA: 5,nameB: 6,nameC: 8}
mon_quickness_dict = {nameA:4,nameB:6,nameC:5}
mon_EXP_dict = {nameA: 4,nameB: 5,nameC: 7}
mon_Gold_dict = {nameA: 2,nameB: 2,nameC: 2}
mon = random.choice(monster_list)
mon_group_list = mon.split()
mon_group_list2 = mon_group_list.copy()
mon_EXP = 0
mon_Gold = 0

for i in range(len(mon_group_list)):  
    status_data.append({
        "type": "monster",
        "name": f"{mon_group_list[i]}",
        "HP": get_value_by_partial_key(mon_HP_dict,mon_group_list[i]),
        "strength": get_value_by_partial_key(mon_strength_dict,mon_group_list[i]),
        "defence": get_value_by_partial_key(mon_defence_dict,mon_group_list[i]),
        "quickness": get_value_by_partial_key(mon_quickness_dict,mon_group_list[i]),
        "image": get_value_by_partial_key(mon_images_dict,mon_group_list[i]),
        "attack_on": 0
    })


# モンスターの位置を定義(奇数・偶数で異なる)
monster_positions = {
    1: [0.5],  # 1体
    2: [0.4, 0.6],  # 2体
    3: [0.3, 0.5, 0.7],  # 3体
    4: [0.2, 0.4, 0.6, 0.8],  # 4体
    5: [0.1, 0.3, 0.5, 0.7, 0.9]  # 5体
}

# モンスターの位置を設定
monster_rects = [
    get_value_by_partial_key(mon_images_dict,mon_group_list[i]).get_rect(center=(width * monster_positions[len(mon_group_list)][i], height * 0.5))
    for i in range(len(mon_group_list))
]

# 魔物がターゲットを決めるリスト
player_select_index_list = [0,1,2,3]
# 魔物がターゲットを決めたインデックス
player_select_index = 0

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

# メインループ
while running:
    clock.tick(60)
    # 画面を黒色に塗りつぶし
    screen.fill((0, 0, 0))
    for i, data in enumerate(player_data):
        if status_visible == 0 and player_select_index == i:
            status_window(data)
        if player_select_index != i:
            status_window(data)
        
    # モンスターの画像表示
    if mon_group_list:
        for i in range(len(mon_group_list)):
            if phase < 3: # current_indexがまだないからphaseを分ける
                screen.blit(get_value_by_partial_key(mon_images_dict,mon_group_list[i]), (monster_rects[i].topleft))
            elif phase >= 3: # モンスターに"mon_select_index"がないから"type"を分ける
                if current_actor["type"] == "monster" or mon_visible == 0 and current_actor["mon_select_index"] == i:
                    screen.blit(get_value_by_partial_key(mon_images_dict,mon_group_list[i]), (monster_rects[i].topleft))
                if current_actor["type"] == "player" and current_actor["mon_select_index"] != i:
                    screen.blit(get_value_by_partial_key(mon_images_dict,mon_group_list[i]), (monster_rects[i].topleft))
    # コマンドウィンドゥ
    if command:
        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, cmd_rect, 3,5)
        text = font.render(chara_group_list[cmd_chara_index], True, white)
        screen.blit(text,((cmd_rectx + 14) + 60,(cmd_recty + 14)))
        draw_text_grid(screen, text_list, start_x=51, start_y=365, spacing_x=98, spacing_y=34, font=font, white = white)  # テキスト描画
        if cmd_cursor:
            screen.blit(cursor, ((cmd_rectx + 5) + 100 * cmd_num2, (cmd_recty + 40) + 34 * cmd_num1))  # カーソル描画
            cmd_index = cmd_num1 + (cmd_num2 * 3)
        # 全体攻撃
        player_data[cmd_chara_index]["equip_index"] = equip_index
        player_data[cmd_chara_index]["equip_effect"] = equip_effect
        none_key = equip_effect_data.get(equip_data[cmd_chara_index]["weapon_name"])  # 存在しない場合は None
        if none_key is not None:
            equip_effect = equip_effect_data[equip_data[cmd_chara_index]["weapon_name"]]
        elif none_key == None:
            equip_effect = 0

        # セレクトウィンドゥ
        if mon_select or masic_phase == 2 and player_data[cmd_chara_index]["masic_list"][player_data[cmd_chara_index]["masic_index"]]["masic_type"] == "攻撃まほう":
            pygame.draw.rect(screen,white,select_rect,3,5)
            # モンスター名の描画
            if mon_group_list:
                for i, mon in enumerate(mon_group_list):
                    text = font.render(mon, True, white)
                    screen.blit(text, ((select_rectx + 14) + 30, (select_recty + 14) + 24 * i))
                screen.blit(cursor, ((select_rectx + 14), (select_recty + 11) + 24 * mon_select_index))  # カーソル描画
        if masic_phase == 2 and player_data[cmd_chara_index]["masic_list"][player_data[cmd_chara_index]["masic_index"]]["masic_type"] == "補助まほう" or item_phase == 2:
            pygame.draw.rect(screen,white,select_rect,3,5)
            # キャラ選択
            # カーソル
            for i, chara in enumerate(chara_group_list):
                text = font.render(chara, True, white)
                screen.blit(text, ((select_rectx + 14) + 30, (select_recty + 14) + 24 * i))
            screen.blit(cursor, ((select_rectx + 14), (select_recty + 11) + 24 * chara_index))  # カーソル描画
        if masic_select and masic_phase <= 1:
            # まほうがある場合のみ描画
            pygame.draw.rect(screen,white,select_rect,3,5)
            if player_data[cmd_chara_index]["masic_list"]:
                for i, masic in enumerate([player_data[cmd_chara_index]["masic_list"][i]["masic_name"] for i in range(len(player_data[cmd_chara_index]["masic_list"]))]):
                    text = font.render(masic, True, white)
                    screen.blit(text, ((select_rectx + 14) + 30, (select_recty + 14) + 24 * i))
                screen.blit(cursor, ((select_rectx + 14), (select_recty + 11) + 24 * masic_index))  # カーソル描画
        if item_select and item_phase <= 1:
            # アイテムがある場合のみ描画
            pygame.draw.rect(screen,white,select_rect,3,5)
            if player_data[cmd_chara_index]["item_list"]:
                player_data[cmd_chara_index]["item_index"] = item_index
                player_data[cmd_chara_index]["item_effect"] = item_effect
                none_key = item_data.get(player_data[cmd_chara_index]["item_list"][player_data[cmd_chara_index]["item_index"]])  # 存在しない場合は None
                if none_key is not None:
                    item_effect = item_data[player_data[cmd_chara_index]["item_list"][player_data[cmd_chara_index]["item_index"]]]["item_effect"]
                elif none_key == None:
                    item_effect = 1
                for i, item in enumerate(player_data[cmd_chara_index]["item_list"]):
                    text = font.render(item, True, (255, 255, 255))
                    screen.blit(text, ((select_rectx + 14) + 30, (select_recty + 14) + 24 * i))
                screen.blit(cursor, ((select_rectx + 14), (select_recty + 11) + 24 * item_index))  # カーソル描画
        if equip_select:
            # 装備品がある場合のみ描画
            pygame.draw.rect(screen,white,select_rect,3,5)
            if player_data[cmd_chara_index]["equip_list"]:
                for i, item in enumerate(player_data[cmd_chara_index]["equip_list"]):
                    text = font.render(item, True, (255, 255, 255))
                    screen.blit(text, ((select_rectx + 14) + 30, (select_recty + 14) + 24 * i))
                for i, item in enumerate(player_data[cmd_chara_index]["E_list"]):
                    text = font.render(item, True, (255, 255, 255))
                    screen.blit(text, ((select_rectx + 14) + 22, (select_recty + 14) + 24 * i))
                screen.blit(cursor, ((select_rectx + 14), (select_recty + 11) + 24 * equip_index))  # カーソル描画
    # メッセージウィンドゥ
    if battle_message:
        pygame.draw.rect(screen, white, message_rect, 3,5)
        # バトルメッセージ
        draw_text(screen,lines,((message_rectx + 24),(message_recty + 24) - text_up_num),font)
        if text_up and text_up_num < 27:
            text_up_num += 1
            if text_up_num == 27:
                text_up = not text_up
                text_up_num = 0
                del lines[0]
        

    # プレイヤーのダメージエフェクト
    if status_flash > 0:
        status_visible = pygame.time.get_ticks() // 90 % 2
        status_flash -= 1
        if status_flash == 19:
            sound2.play()
    if status_flash == 1:
        status_flash = 0
        status_visible = 0
        # キャラの死亡
        if player_data[player_select_index]["HP"] <= 0:
            if player_data[player_select_index]["attack_on"] == 1:
                actor_index -= 1
            del status_data[player_select_index_list.index(player_select_index) + len(mon_group_list)]
            del player_select_index_list[player_select_index_list.index(player_select_index)]
        if len(player_select_index_list) == 0:        
            bgm(lose_bgm)
            message = "そのあと\nゆうしゃのすがたをみたものはいない"
            phase = 4
        else:
            phase = 2
    # モンスターのダメージエフェクト
    if mon_flash > 0:
        mon_visible = pygame.time.get_ticks() // 90 % 2
        mon_flash -= 1
        if mon_flash == 19:
            sound2.play()
    if mon_flash == 1:
        mon_flash = 0
        mon_visible = 0
        if status_data[current_actor["mon_select_index"]]["HP"] <= 0: 
            defeat = True
        else:
            phase = 2
                
    # まほう(半透明レクト)
    if masic_frame > 0:
        if current_actor["type"] == "player":
            if current_actor["MP"] >= current_actor["masic_list"][current_actor["masic_index"]]["MP"]:
                screen.blit(current_actor["masic_list"][current_actor["masic_index"]]["surface"],(0,0))
                masic_frame -= 1

    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 and mon_flash == 0 and status_flash == 0:
                # あらわれた!を消してコマンドウィンドゥをひらく
                if phase == 0:
                    sound.play()                        
                    battle_message = False # あらわれた!を消す
                    command = True
                    cmd_cursor = True
                    phase = 1
                # コマンドウィンドゥを開いたまま、魔物選択ウィンドゥをひらく
                # 「たたかう」
                elif phase == 1 and cmd_index == 0 and equip_effect != "全体攻撃":
                    sound.play()                        
                    mon_select = True
                    cmd_cursor = False
                    phase = 2
                # コマンドウィンドゥを開いたまま、まほう選択ウィンドゥをひらく
                # 「まほう」
                elif phase == 1 and cmd_index == 1 and chara_group_list[cmd_chara_index] != "せんし":
                    player_data[cmd_chara_index]["masic_index"] = masic_index
                    sound.play()                        
                    masic_select = True
                    cmd_cursor = False
                    masic_phase = min(2,masic_phase + 1)
                    if masic_phase == 2:
                        phase = 2
                # コマンドウィンドゥを開いたまま、アイテム選択ウィンドゥをひらく
                # 「アイテム」
                elif phase == 1 and cmd_index == 3 and item_effect != 1 and player_data[cmd_chara_index]["item_list"]:
                    sound.play()                        
                    item_select = True
                    cmd_cursor = False
                    item_phase = min(2,item_phase + 1)
                    if item_phase == 2:
                        phase = 2
                # コマンドウィンドゥを開いたまま、そうび選択ウィンドゥをひらく
                # 「そうび」
                elif phase == 1 and cmd_index == 4:
                    sound.play()                        
                    if equip_select:
                        current_item =  player_data[cmd_chara_index]["equip_list"][equip_index][1:]
                        current_E =  player_data[cmd_chara_index]["E_list"][equip_index]
                        for category, data_dict in equip_categories.items():
                            if current_item in data_dict:
                                if current_E == "":
                                    # 装備する
                                    if category == "weapon":
                                        equip_data[cmd_chara_index]["weapon_name"] = current_item
                                    elif category == "helmet":
                                        equip_data[cmd_chara_index]["helmet_name"] = current_item
                                    elif category == "shield":
                                        equip_data[cmd_chara_index]["shield_name"] = current_item
                                    elif category == "armor":
                                        equip_data[cmd_chara_index]["armor_name"] = current_item

                                    for i, item in enumerate(player_data[cmd_chara_index]["equip_list"]):
                                        if item[1:] in equip_categories[category]:
                                            player_data[cmd_chara_index]["E_list"][i] = ""
                                    player_data[cmd_chara_index]["E_list"][equip_index] = "E"

                                elif current_E == "E":
                                    # 外す
                                    if category == "weapon":
                                        equip_data[cmd_chara_index]["weapon_name"] = "なし"
                                    elif category == "helmet":
                                        equip_data[cmd_chara_index]["helmet_name"] = "なし"
                                    elif category == "shield":
                                        equip_data[cmd_chara_index]["shield_name"] = "なし"
                                    elif category == "armor":
                                        equip_data[cmd_chara_index]["armor_name"] = "なし"
                                    player_data[cmd_chara_index]["E_list"][equip_index] = ""
                                break  # 該当するカテゴリを処理したら終了
                        # ステータス再計算と出力
                        player_data[cmd_chara_index]["power"] = calc_power(player_data[cmd_chara_index]["strength"], equip_data[cmd_chara_index]["weapon_name"])
                        player_data[cmd_chara_index]["defence"] = calc_defence(player_data[cmd_chara_index]["tough"], equip_data[cmd_chara_index]["helmet_name"], equip_data[cmd_chara_index]["shield_name"], equip_data[cmd_chara_index]["armor_name"])
                    equip_select = True
                    cmd_cursor = False
                elif phase == 2 or phase == 1 and cmd_index == 2 or phase == 1 and cmd_index == 5 or phase == 1 and item_effect == 1 or phase == 1 and equip_effect == "全体攻撃":
                    if cmd_chara_index < len(chara_group_list) - 1:
                        player_data[cmd_chara_index]["cmd_index"] = cmd_index
                        player_data[cmd_chara_index]["mon_select_index"] = mon_select_index
                        player_data[cmd_chara_index]["chara_index"] = chara_index
                    # 死亡キャラのスキップ
                    if command:
                        for i, item in enumerate(player_data):
                            if i <= cmd_chara_index:
                                continue
                            if item["HP"] == 0:
                                cmd_chara_index += 1
                            else:
                                break
                    # コマンド入力のループ
                    if cmd_chara_index < len(chara_group_list) - 1:
                        cmd_chara_index += 1
                        mon_select_index = 0
                        masic_index = 0
                        item_index = 0
                        masic_phase = 0                        
                        item_phase = 0
                        masic_effect = 0
                        item_effect = 0
                        chara_index = 0
                        cmd_index, cmd_num1,cmd_num2 = 0, 0, 0
                        sound.play()
                        battle_message, command, masic_select, item_select, cmd_cursor, mon_select = False, True, False, False, True, False
                        phase = 1
                    # 魔物選択ウィンドゥを消して、メッセージの表示
                    elif cmd_chara_index == len(chara_group_list) - 1:
                        if not all_select:
                            player_data[cmd_chara_index]["cmd_index"] = cmd_index
                            player_data[cmd_chara_index]["masic_index"] = masic_index
                            player_data[cmd_chara_index]["mon_select_index"] = mon_select_index
                            player_data[cmd_chara_index]["chara_index"] = chara_index
                            if turn_num <= 1:
                                status_data += player_data
                            command = False
                            mon_select = False
                            masic_phase = 3
                            battle_message = True
                            all_select = True
                        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()
                            if current_actor["type"] == "player":
                                if current_actor["cmd_index"] == 0:
                                    lines = [f'{current_actor["name"]}の こうげき!']
                                elif current_actor["cmd_index"] == 1:
                                    lines = [f'{current_actor["name"]}は {current_actor["masic_list"][current_actor["masic_index"]]["masic_name"]}を となえた!']
                                    masic_effect = current_actor["masic_list"][current_actor["masic_index"]]["masic_effect"]
                                    masic_frame = 10
                                elif current_actor["cmd_index"] == 2:
                                    lines = [f'{current_actor["name"]}は ガードした']
                                    actor_index += 1
                                    current_actor["attack_on"] = 1
                                elif current_actor["cmd_index"] == 3:
                                    lines = [f'{current_actor["name"]}は {current_actor["item_list"][current_actor["item_index"]]}を つかった!']
                                elif current_actor["cmd_index"] == 5:
                                    lines = [f'{current_actor["name"]}は にげだした']
                            else:
                                lines = [f'{current_actor["name"]}の こうげき!']
                                
                            if current_actor["type"] == "player":
                                if current_actor["cmd_index"] == 2:
                                    pass
                                elif current_actor["cmd_index"] == 5:                                    
                                    phase = 4
                                else:
                                    phase= 3
                            else:
                                phase = 3
                        # ターン終了したら、コマンドウィンドゥをひらく
                        elif actor_index == len(status_data):
                            player_select_list = []
                            turn_num += 1
                            cmd_chara_index = 0
                            actor_index = 0
                            mon_select_index = 0
                            masic_index = 0
                            item_index = 0
                            masic_phase = 0                        
                            item_phase = 0
                            masic_effect = 0
                            item_effect = 0
                            cmd_index, cmd_num1,cmd_num2 = 0, 0, 0
                            sound.play()
                            battle_message, command, masic_select, item_select, cmd_cursor, all_select, is_all_attack = False, True, False, False, True, False, False
                            phase = 1
                            for i in range(len(status_data)):
                                status_data[i]["attack_on"] = 0
                            for item in player_data:
                                if item["HP"] == 0:
                                    cmd_chara_index += 1
                                else:
                                    break
                # プレイヤーの攻撃(モンスターに与えるダメージ)
                elif phase == 3 and current_actor["type"] == "player" and not defeat:
                    # 全体攻撃
                    if current_actor["equip_effect"] != 0 and equip_effect_data[equip_data[current_actor["num"]]["weapon_name"]] == "全体攻撃":
                        if not is_all_attack:
                            current_actor["mon_select_index"] = 0
                        else:
                            current_actor["mon_select_index"] += 1
                        is_all_attack = True                            
                    # MP判定
                    if current_actor["cmd_index"] == 1 and current_actor["MP"] < current_actor["masic_list"][current_actor["masic_index"]]["MP"]:
                        message = "MPが足りない…"
                        phase = 2
                    # ダメージ計算
                    elif current_actor["cmd_index"] == 0 or current_actor["cmd_index"] == 1 and current_actor["masic_list"][current_actor["masic_index"]]["masic_type"] == "攻撃まほう":
                        random_value = random.random() # 0.0以上1.0未満をランダムで生成
                        if random_value < Decimal("1.00") - Decimal("0.05") or current_actor["cmd_index"] == 1: # 0.00以上0.95未満
                            critical = 1 # キャラごとに初期化
                            if current_actor["cmd_index"] == 0:
                                if random_value > Decimal("1.00") - Decimal("0.10"): # 0.90以上0.95未満
                                    critical = 1.5
                                    lines.append(f'強烈な一撃!')
                                mon_damage = current_actor["power"] // 2 - status_data[current_actor["mon_select_index"]]["defence"] // 4
                                mon_damage *= critical
                            elif current_actor["cmd_index"] == 1:
                                mon_damage = current_actor["masic_list"][current_actor["masic_index"]]["数値"]
                                current_actor["MP"] -= current_actor["masic_list"][current_actor["masic_index"]]["MP"]
                            mon_damage = max(1, mon_damage)
                            mon_damage = random.randint(int(mon_damage),int(mon_damage * 1.5))
                            if mon_damage <= 0:
                                mon_damage = 1
                            status_data[current_actor["mon_select_index"]]["HP"] -= mon_damage
                            lines.append(f'{status_data[current_actor["mon_select_index"]]["name"]}に {mon_damage}の ダメージ!' )
                            mon_flash = 20
                        elif random_value >= Decimal("1.00") - Decimal("0.05") and current_actor["cmd_index"] != 1: # 0.95以上
                            lines.append(f"ミス") 
                            lines.append(f'{status_data[current_actor["mon_select_index"]]["name"]}に ダメージを与えられない')
                            phase = 2
                    elif current_actor["cmd_index"] == 1 and current_actor["masic_list"][masic_index]["masic_type"] == "補助まほう":
                        # まほう(回復)
                        if masic_effect == 2:
                            if current_actor["MP"] >= current_actor["masic_list"][current_actor["masic_index"]]["MP"]:
                                recovery  = random.randint(current_actor["masic_list"][current_actor["masic_index"]]["数値"],int(current_actor["masic_list"][current_actor["masic_index"]]["数値"] * 1.5))
                                player_data[current_actor["chara_index"]]["HP"] = min(player_data[current_actor["chara_index"]]["Max_HP"],player_data[current_actor["chara_index"]]["HP"] + recovery)
                                lines.append(f'{chara_group_list[current_actor["chara_index"]]}の きずが かいふくした!') 
                        current_actor["MP"] -= current_actor["masic_list"][current_actor["masic_index"]]["MP"]
                        phase = 2
                    elif current_actor["cmd_index"] == 3:
                        # アイテム(回復)
                        if current_actor["item_effect"] == 2:
                            recovery  = random.randint(item_data[current_actor["item_list"][current_actor["item_index"]]]["item_parameter"],int(item_data[current_actor["item_list"][current_actor["item_index"]]]["item_parameter"] * 1.5))
                            player_data[current_actor["chara_index"]]["HP"] = min(player_data[current_actor["chara_index"]]["Max_HP"],player_data[current_actor["chara_index"]]["HP"] + recovery)
                            lines.append(f'{chara_group_list[current_actor["chara_index"]]}の きずが かいふくした!')
                            del current_actor["item_list"][current_actor["item_index"]]
                        # アイテム効果なし
                        elif current_actor["item_effect"] == 1:
                            item_effect = 0
                            lines = ["しかし、なにもおこらなかった…"]
                        phase = 2
                    if current_actor["equip_effect"] == 0:
                        actor_index += 1
                    elif equip_effect_data[equip_data[current_actor["num"]]["weapon_name"]] == "全体攻撃" and current_actor["mon_select_index"] == len(mon_group_list) - 1: 
                        actor_index += 1
                    current_actor["attack_on"] = 1
                # モンスターを一体たおした時の処理
                elif defeat:
                    lines.append(f'{status_data[current_actor["mon_select_index"]]["name"]}をたおした!')
                    if status_data[current_actor["mon_select_index"]]["attack_on"] == 1:
                        actor_index -= 1
                    del mon_group_list[current_actor["mon_select_index"]]
                    del monster_rects[current_actor["mon_select_index"]]
                    del status_data[current_actor["mon_select_index"]]
                    if current_actor["equip_effect"] != 0 and equip_effect_data[equip_data[current_actor["num"]]["weapon_name"]] == "全体攻撃":
                        current_actor["mon_select_index"] = current_actor["mon_select_index"] - 1                    
                    defeat = False
                    phase = 2
                    # 自動送り
                    for data in status_data2:
                        if data["type"] == "player":
                            # 範囲外を防ぐ
                            if data["mon_select_index"] > len(mon_group_list) - 1:
                                data["mon_select_index"] = len(mon_group_list) - 1
                            # ターゲットがズレるのを防ぐ
                            elif data["attack_on"] == 0:
                                if current_actor["mon_select_index"] < data["mon_select_index"] and data["mon_select_index"] != 0:
                                    data["mon_select_index"] -= 1
                    # モンスターをすべてたおした時の処理
                    if len(mon_group_list) == 0:
                        bgm(win_bgm)
                        lines = ["モンスターたちをやっつけた!"]
                        phase = 5
                # モンスターの攻撃(プレイヤーに与えるダメージ)
                elif phase == 3:
                    sound.play()
                    for i in range(len(mon_group_list)):
                        if current_actor["name"] == status_data[i]["name"]:
                            # 毎回リストを初期化する
                            player_select_index = random.choice(player_select_index_list)
                            random_value = random.random() # 1.0未満~0.0以上をランダムで生成
                            if random_value < Decimal("1.00") - Decimal("0.05"): # 0.00以上0.95未満
                                critical = 1
                                if random_value >= Decimal("1.00") - Decimal("0.10"): # 0.90以上0.95未満
                                    critical = 1.5
                                    lines.append(f'強烈な一撃!')
                                player_damage = status_data[i]["strength"] // 2 - player_data[player_select_index]["defence"] // 4
                                player_damage *= critical
                                player_damage = max(1,player_damage)
                                player_damage = random.randint(int(player_damage),int(player_damage * 1.5))
                                if player_data[player_select_index]["cmd_index"] == 2:
                                    player_damage = int(player_damage * 0.6)
                                player_data[player_select_index]["HP"] -= player_damage
                                lines.append(f'{player_data[player_select_index]["name"]}に {player_damage}のダメージ!')
                                status_flash = 20
                                if player_data[player_select_index]["HP"] <= 0:
                                    player_data[player_select_index]["HP"] = 0
                            elif random_value >= Decimal("1.00") - Decimal("0.05"): # 0.95以上
                                lines.append(f"ミス") 
                                lines.append(f'{player_data[player_select_index]["name"]}に ダメージを与えられない')
                                phase = 2
                    current_actor["attack_on"] = 1
                    actor_index += 1
                # ワンテンポずらす
                elif phase == 4:
                    sound.play()
                    if len(player_select_index_list) == 0 or current_actor["cmd_index"] == 5: 
                        phase = 8
                    elif len(lines) >= 4:
                        text_up = True
                    elif level_up_chara_num == len(chara_group_list) - 1: # phase == 6とは終了の条件が違う(level_up_chara_num)
                        phase = 8
                    # 連続でレベルが上がるときのため
                    elif EXP_dict[chara_group_list[level_up_chara_num]] >= level_up_list[status_data[level_up_chara_num]["name"]][level_up_index[chara_group_list[level_up_chara_num]]]:
                        phase = 6
                        status_up_list = []
                    else:
                        phase = 6
                        status_up_list = []
                        level_up_chara_num += 1
                        
                # 経験値とお金
                elif phase == 5:
                    sound.play()
                    for i in range(len(mon_group_list2)):
                        mon_EXP += get_value_by_partial_key(mon_EXP_dict,mon_group_list2[i])
                        mon_Gold += get_value_by_partial_key(mon_Gold_dict,mon_group_list2[i])
                    lines.append(f"けいけんち {mon_EXP}かくとく")
                    lines.append(f"{mon_Gold}ゴールドを てにいれた")
                    for key, value in EXP_dict.items():
                        EXP_dict[key] += mon_EXP
                    Gold += mon_Gold
                    mon_EXP = 0
                    mon_Gold = 0
                    phase = 6
                # レベルアップ
                elif phase == 6:
                    if level_up_chara_num < len(status_data):
                        for i in range(len(status_data)):
                            if EXP_dict[status_data[level_up_chara_num]["name"]] >= level_up_list[status_data[level_up_chara_num]["name"]][level_up_index[status_data[level_up_chara_num]["name"]]]:
                                pygame.mixer.music.pause()
                                sound3.play()
                                level_up_index[status_data[level_up_chara_num]["name"]] += 1
                                lines.append(f'{status_data[level_up_chara_num]["name"]}の レベルが上がった!')
                                phase = 7
                                break
                            else:
                                level_up_chara_num += 1
                    elif level_up_chara_num == len(status_data):
                        phase = 8
                elif phase == 7:
                    time.sleep(1)
                    pygame.mixer.music.unpause()
                    sound.play()

                    # 各ステータスの上昇値を決定
                    for _ in range(5):
                        loto = random.choice(hit_and_miss)
                        status_up_list.append(random.randint(1, 3) if loto == 1 else 0)

                    # ステータスアップのメッセージ作成
                    for i, value in enumerate(status_up_list):
                        if value != 0:
                            lines.append(f"{status_names[i]}が {value}ポイント 上がった!")
                            status_data[level_up_chara_num][status_names_dict[status_names[i]]] += value

                    status_data[level_up_chara_num]["level"] += 1
                    phase = 4
                elif phase == 8:
                    sound.play()
                    pygame.quit()
                    sys.exit()
                        
            #方向キー
            if event.type == KEYDOWN:
                if command and not mon_select and not masic_select and not item_select and not equip_select:
                    if event.key == K_DOWN:
                        cmd_num1 = (cmd_num1 + 1) % 3  # 下へ移動
                    if event.key == K_UP:
                        cmd_num1 = (cmd_num1 - 1) % 3  # 上へ移動
                    if event.key == K_RIGHT:
                        cmd_num2 = (cmd_num2 + 1) % 2  # 下へ移動
                    if event.key == K_LEFT:
                        cmd_num2 = (cmd_num2 - 1) % 2  # 下へ移動
                if mon_select or masic_phase == 2 and player_data[cmd_chara_index]["masic_list"][player_data[cmd_chara_index]["masic_index"]]["masic_type"] == "攻撃まほう":
                    if event.key == K_DOWN:
                        mon_select_index = (mon_select_index + 1) % len(mon_group_list)  # 下へ移動
                    if event.key == K_UP:
                        mon_select_index = (mon_select_index - 1) % len(mon_group_list)  # 上へ移動
                if masic_phase == 2 and player_data[cmd_chara_index]["masic_list"][player_data[cmd_chara_index]["masic_index"]]["masic_type"] == "補助まほう" or item_effect == 2:
                    if event.key == K_DOWN:
                        chara_index = (chara_index + 1) % len(chara_group_list)  # 下へ移動
                    if event.key == K_UP:
                        chara_index = (chara_index - 1) % len(chara_group_list)  # 上へ移動
                if masic_select and masic_phase <= 1:
                    if event.key == K_DOWN:
                        masic_index = (masic_index + 1) % len(player_data[cmd_chara_index]["masic_list"])  # 下へ移動
                    if event.key == K_UP:
                        masic_index = (masic_index - 1) % len(player_data[cmd_chara_index]["masic_list"])  # 上へ移動
                if item_select and item_phase <= 1:
                    if event.key == K_DOWN:                        
                        item_index = (item_index + 1) % len(player_data[cmd_chara_index]["item_list"])  # 下へ移動
                    if event.key == K_UP:
                        item_index = (item_index - 1) % len(player_data[cmd_chara_index]["item_list"])  # 上へ移動
                if equip_select:
                    if event.key == K_DOWN:                        
                        equip_index = (equip_index + 1) % len(player_data[cmd_chara_index]["equip_list"])  # 下へ移動
                    if event.key == K_UP:
                        equip_index = (equip_index - 1) % len(player_data[cmd_chara_index]["equip_list"])  # 上へ移動
                        
                # キャンセル
                if event.key == K_x:
                    if command and not mon_select and not masic_select and not item_select and not equip_select:
                        if cmd_chara_index != 0:
                            sound.play()                        
                            cmd_chara_index -= 1
                    if cmd_index == 0 and phase == 2:
                        sound.play()                        
                        command = True
                        cmd_cursor = True
                        mon_select = False
                        mon_select_index = 0
                        phase = 1
                    if cmd_index == 1 and masic_phase == 1:
                        sound.play()                        
                        command = True
                        cmd_cursor = True
                        masic_select = False
                        masic_index = 0
                        masic_phase = 0
                    if cmd_index == 1 and masic_phase == 2:
                        sound.play()                        
                        masic_select = True
                        masic_index = 0
                        mon_select_index = 0
                        chara_index = 0
                        masic_phase = 1
                        phase = 1
                    if cmd_index == 3 and item_phase == 1:
                        sound.play()                        
                        command = True
                        cmd_cursor = True
                        item_select = False
                        item_index = 0
                        item_phase = 0
                        item_effect = 0
                    if cmd_index == 3 and item_phase == 2:
                        sound.play()                        
                        item_select = True
                        item_index = 0
                        chara_index = 0
                        item_phase = 1
                        item_effect = 0
                        phase = 1
                    if equip_select:
                        sound.play()                        
                        equip_select = False
                        cmd_cursor = True
                        epuip_index = 0
                    
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?