Godot中D20战斗系统代码求助:回合交替与循环失效
Godot D20战斗系统问题排查与规范解答
一、攻击者连续攻击两次的问题
核心问题是回合切换时的参数传递错误,以及部分逻辑的顺序问题:
- 初始
_start_combat中,turn(enemy, player)的参数是对的(turn(target, attacker),即玩家攻击敌人),但在turn函数的miss分支、damage函数的回合切换分支,你错误地调用了_start_combat(attacker,target)——_start_combat的参数要求是player, enemy,传递交换后的角色会导致回合逻辑混乱,出现连续攻击。 - 另外建议把
player和enemy存为AutoLoad的全局变量,避免每次重复传递,减少参数错误概率。
修正思路:切换回合后调用_start_combat时,传入全局存储的玩家和敌人,而非临时的attacker和target。
二、for循环无法输出2个数值的问题
你的循环代码里第一次迭代就执行了return,直接跳出了循环,导致永远只执行一次骰子投掷:
for n in attacker.row: dmg_roll += roll(attacker.dice) print(dmg_roll) return damage(target, attacker, dmg_roll) # 这里直接return,循环只走一次
修正方法:将return移出循环,等所有骰子投掷完成后再调用damage函数:
var dmg_roll : int = 0 for n in attacker.row: var single_roll = roll(attacker.dice) dmg_roll += single_roll print("单次骰子结果:", single_roll, " | 当前总伤害:", dmg_roll) # 循环结束后统一处理伤害 damage(target, attacker, dmg_roll)
三、函数接收参数与传入变量同名是否规范?
这在GDScript(以及绝大多数编程语言)里是完全规范且推荐的做法。比如你示例中的:
func turn(target, attacker): ... damage(target, attacker, dmg_roll) func damage(target, attacker, dmg_roll): ...
函数参数是局部变量,仅在函数内部生效,不会与外部同名变量冲突。这种命名方式能让代码逻辑更清晰,避免冗余命名(比如target_param这种不必要的后缀)。
修正后的完整代码示例
extends Node2D var enemy_turn : bool = false var critical_Hit : bool = false # 全局存储对战双方,避免重复传递参数 var current_player = null var current_enemy = null func _start_combat(player, enemy): current_player = player current_enemy = enemy if enemy_turn == false: # 玩家回合:玩家攻击敌人 turn(current_enemy, current_player) else: # 敌人回合:敌人攻击玩家 turn(current_player, current_enemy) func roll(dice) -> int: var random_number = RandomNumberGenerator.new() random_number.randomize() return random_number.randi_range(1, dice) func turn(target, attacker): print(attacker.char_name, " 攻击 ", target.char_name) var iniciative_roll = roll(20) print(" Initiative d20: ", iniciative_roll) critical_Hit = false if iniciative_roll == 20: print("暴击!") critical_Hit = true elif iniciative_roll >= abs(target.ac - attacker.thac0): pass # 普通命中,critical_Hit保持false else: print(attacker.char_name, " 攻击落空。") enemy_turn = !enemy_turn _start_combat(current_player, current_enemy) return var dmg_roll : int = 0 for n in attacker.row: var single_roll = roll(attacker.dice) dmg_roll += single_roll print(" 骰子投掷:", single_roll, " | 当前累计伤害:", dmg_roll) # 循环结束后处理伤害结算 damage(target, attacker, dmg_roll) func damage(target, attacker, aux): var final_damage = aux if critical_Hit == true: final_damage = aux * 2 target.hp -= final_damage print(attacker.char_name, " 打出暴击!对 ", target.char_name, " 造成 ", final_damage, " 点伤害") else: target.hp -= final_damage print(attacker.char_name, " 对 ", target.char_name, " 造成 ", final_damage, " 点伤害") if target.hp <= 0: target._death() else: enemy_turn = !enemy_turn _start_combat(current_player, current_enemy)
内容的提问来源于stack exchange,提问作者Marcelo João
相关产品推荐
相关产品推荐

