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