序列冷却机制异常:3次充能技能无法按预期恢复
3次充能技能系统实现问题
需求
实现一个带3次充能的技能系统:
- 使用一次充能后,仅恢复该次充能
- 若在恢复过程中使用另一次充能,需将前一次的恢复进度转移到新使用的充能上
当前尝试
通过条件判断与await语句,基于当前剩余充能数创建冷却逻辑。
问题现象
充能未完全恢复时使用技能,充能数会超过设定的最大值(3)。
现有代码
extends RigidBody2D @export var RotationSpeed = 4.2 @export var JumpPower = 1000 @onready var jumpcount: int = 3 @onready var timerRunning: bool = false var animationTime: float var continue1: bool = true var continue2: bool = true func _ready(): Gwobaw.Player = self $Sprite2D/GPUParticles2D.z_index = -5 $Sprite2D/GPUParticles2D.emitting = true func Jump(): if(jumpcount > 0): if $RayCast2D.is_colliding(): var enemy = $RayCast2D.get_collider() enemy.Health -= 100 linear_velocity = -transform.y * JumpPower $Sprite2D/GPUParticles2D.emitting = true $Sprite2D/GPUParticles2D.z_index = -1 jumpcount -= 1 func _process(delta): $CanvasLayer/Label.text = str(jumpcount) if Input.is_action_pressed("ui_right"): angular_velocity = RotationSpeed if Input.is_action_pressed("ui_left"): angular_velocity = -RotationSpeed if Input.is_action_just_pressed("Boost"): if(jumpcount == 3): Jump() await get_tree().create_timer(5).timeout if(continue1 == true): jumpcount -= 1 elif(jumpcount == 2): Jump() continue1 = false await get_tree().create_timer(5).timeout if(continue2 == true): jumpcount += 1 await get_tree().create_timer(5).timeout jumpcount += 1 continue1 = true elif(jumpcount == 1): continue2 = false Jump() await get_tree().create_timer(5).timeout jumpcount += 1 await get_tree().create_timer(5).timeout jumpcount += 1 await get_tree().create_timer(5).timeout jumpcount += 1 continue2 = true
问题分析
现有代码的核心问题:
- 用
continue1/continue2这类标记变量控制恢复逻辑,状态易混乱且不同步 - 硬编码多个
await累加充能,无法实现“进度转移”的核心需求 - 未限制充能上限,导致恢复时可能超过最大值3
正确实现方案
要实现“进度转移”的充能机制,需维护当前冷却的剩余时间,当再次使用技能时直接重置冷却计时器,将进度继承到新的充能冷却中。以下是简洁的实现方式:
修正后的代码
extends RigidBody2D @export var RotationSpeed = 4.2 @export var JumpPower = 1000 @export var max_charges: int = 3 # 最大充能数 @export var charge_cooldown: float = 5.0 # 单充能冷却时间 var available_charges: int = 3 var current_cooldown_timer: Timer = null var is_cooldown_running: bool = false func _ready(): Gwobaw.Player = self $Sprite2D/GPUParticles2D.z_index = -5 $Sprite2D/GPUParticles2D.emitting = true func Jump(): if available_charges > 0: if $RayCast2D.is_colliding(): var enemy = $RayCast2D.get_collider() enemy.Health -= 100 linear_velocity = -transform.y * JumpPower $Sprite2D/GPUParticles2D.emitting = true $Sprite2D/GPUParticles2D.z_index = -1 available_charges -= 1 # 处理进度转移:重置当前冷却,继承到新充能 if is_cooldown_running: current_cooldown_timer.stop() current_cooldown_timer.start(charge_cooldown) else: start_cooldown() func start_cooldown(): is_cooldown_running = true current_cooldown_timer = Timer.new() current_cooldown_timer.wait_time = charge_cooldown current_cooldown_timer.one_shot = true add_child(current_cooldown_timer) current_cooldown_timer.start() # 冷却完成后恢复充能,未到上限则自动续充 await current_cooldown_timer.timeout current_cooldown_timer.queue_free() is_cooldown_running = false available_charges = min(available_charges + 1, max_charges) if available_charges < max_charges: start_cooldown() func _process(delta): $CanvasLayer/Label.text = str(available_charges) if Input.is_action_pressed("ui_right"): angular_velocity = RotationSpeed if Input.is_action_pressed("ui_left"): angular_velocity = -RotationSpeed if Input.is_action_just_pressed("Boost"): Jump()
代码说明
- 状态管理:用
available_charges跟踪可用充能,max_charges限制上限,避免溢出 - 进度转移:使用技能时若已有冷却在运行,直接重置计时器,实现进度继承
- 自动续充:冷却完成后恢复一个充能,未达上限则自动启动下一轮冷却
- 资源清理:冷却完成后及时销毁计时器,避免内存泄漏
内容的提问来源于stack exchange,提问作者Dentr
相关产品推荐
相关产品推荐

