You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

问题根源

  1. 在select_callback方法中,执行了self.monster_currenthealth = monster_currenthealth,将实例变量重新赋值为全局初始值,覆盖了之前更新后的血量
  2. 在monster_attack方法中,同样执行了self.hero_currenthealth = hero_currenthealth,导致英雄血量被重置为全局初始值
  3. 每次创建新视图时虽然传递了当前血量,但回调中的重置操作直接让血量回滚

修复方案

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 16:15:57