Discord.py RPG战斗下拉菜单复用后生命值重置问题求助
问题:Discord.py RPG战斗中生命值无法持久更新
我正在开发一款基于Discord.py的宝可梦风格RPG游戏,战斗流程如下:
- 玩家(英雄)遭遇敌人后,显示带有当前生命值的操作下拉菜单,包含攻击选项
- 选择攻击后,英雄对敌人造成伤害,随后敌人反击玩家
- 重复显示菜单,直至英雄或敌人死亡
问题表现
首次攻击后双方生命值更新正常,但第二次攻击时,全局变量hero_currenthealth和monster_currenthealth会重置为初始值,再应用本次攻击伤害,导致每次攻击都基于初始生命值计算,无法保留之前的血量变化。
hero_currenthealth和monster_currenthealth为全局变量,在主类初始阶段赋值,战斗逻辑核心代码如下:
class get_hero_actions(View): # battle actions input (will be used when hero fights a monster) def __init__(self, rpg_cog, monster_currenthealth, hero_currenthealth,...original_message=None): super().__init__() self.rpg_cog = rpg_cog self.monster_currenthealth = monster_currenthealth self.hero_currenthealth = hero_currenthealth ... self.original_message = original_message @discord.ui.select( placeholder="Choose an action to do", options=[ discord.SelectOption(label="Physical Attack", value="1"),...] ) async def select_callback(self, interaction, select): select.disabled=True if select.values[0] == "1": # chose to physical attack if self.hero_attack_hits(): damage = self.calculate_hero_damage() # calculate damage self.monster_currenthealth = monster_currenthealth self.monster_currenthealth -= damage if self.monster_currenthealth <= 0: # monster died (ran out of health) await ctx.author.send(f"You defeated **{monster_name}**") else: # monster attack await self.monster_attack() self.stop() # # Monster Attack section ############################################################################ # Monster's attack async def monster_attack(self): monster_damage = self.calculate_monster_damage() self.hero_currenthealth = hero_currenthealth # needed this for the first attack to correctly update the health self.hero_currenthealth -= monster_damage if self.hero_currenthealth <= 0: # hero died (ran out of health) await ctx.author.send("You have been defeated!") else: # hero's turn get_hero_actions_view = get_hero_actions(self.rpg_cog, self.monster_currenthealth, self.hero_currenthealth, ... self.original_message) updated_message_content = f"_ _ \nYour current health is **{self.hero_currenthealth}**/**{hero_totalhealth}** \n\n **{monster_name}** current health is **{self.monster_currenthealth}**" # 直接编辑原消息,无需发送新消息 await self.original_message.edit(content=updated_message_content, view=get_hero_actions_view) # # 初始化战斗菜单 get_hero_actions_view = get_hero_actions(self, monster_currenthealth, hero_currenthealth, ...) hero_actions = await ctx.author.send(f"_ _ \nYour current health is **{hero_currenthealth}**/**{hero_totalhealth}**", view=get_hero_actions_view) get_hero_actions_view.original_message = hero_actions
问题根源
- 在
select_callback方法中,执行了self.monster_currenthealth = monster_currenthealth,将实例变量重新赋值为全局初始值,覆盖了之前更新后的血量 - 在
monster_attack方法中,同样执行了self.hero_currenthealth = hero_currenthealth,导致英雄血量被重置为全局初始值 - 每次创建新视图时虽然传递了当前血量,但回调中的重置操作直接让血量回滚
修复方案
1. 移除全局变量重置操作
删除回调中对全局变量的赋值语句,直接使用实例变量进行血量计算:
# 在select_callback中修改 if self.hero_attack_hits(): damage = self.calculate_hero_damage() # 删掉这行:self.monster_currenthealth = monster_currenthealth self.monster_currenthealth -= damage # 在monster_attack中修改 monster_damage = self.calculate_monster_damage() # 删掉这行:self.hero_currenthealth = hero_currenthealth self.hero_currenthealth -= monster_damage
2. 优化消息更新逻辑
无需发送新消息,直接编辑原战斗菜单消息,避免冗余消息同时确保状态同步:
async def monster_attack(self): monster_damage = self.calculate_monster_damage() self.hero_currenthealth -= monster_damage if self.hero_currenthealth <= 0: await ctx.author.send("You have been defeated!") else: get_hero_actions_view = get_hero_actions(self.rpg_cog, self.monster_currenthealth, self.hero_currenthealth, ..., self.original_message) updated_content = f"_ _ \nYour current health is **{self.hero_currenthealth}**/**{hero_totalhealth}** \n\n **{monster_name}** current health is **{self.monster_currenthealth}**" await self.original_message.edit(content=updated_content, view=get_hero_actions_view)
3. 确保视图初始化时传递正确参数
创建新的get_hero_actions视图时,必须传递更新后的self.monster_currenthealth和self.hero_currenthealth,确保新菜单使用最新血量数据。
内容的提问来源于stack exchange,提问作者BigWorm93
相关产品推荐
相关产品推荐

