'''冲刺控制组件 注:该组件只适用于继承自CharaterBody2D的角色。 基础移动控制: 外部调用移动: dash() full_recover_dash_count() recover_dash_count() 内部调用: speed_approach() 此函数将当前速度趋近向目标速度 ''' class_name DashComponent extends ComponentBase ##最大的冲刺次数 @export var maxium_dash_count:int = 1 ##Dash时的速度 @export var dash_speed: float = 240 ##结束Dash的速度 @export var end_dash_speed: float = 160 ##Dash的冷却时间 @export var dash_cold_down: float = .2 ##是否在组件ready时自动补充所有的Dash次数 @export var auto_recover_dash_count_at_ready: bool = true var characterbody:CharacterBody2D var last_dash_count: int ##此变量为总开关,如果关闭,则在物理更新里无论如何也是不会更新Dash的,这里默认为false,因为Dash需要手动触发,最好不要常开 var can_dash: bool = false var _dash_timer: float #Dash计时器 var _is_dashing: bool = false #标记Dash状态 var _dash_direction: Vector2 #存储Dash的Direction ##当Dash count 重置为最大时,发出 signal dash_count_recovered signal dash_brusted signal dash_prepared func _init_component()-> void: characterbody = component_owner as CharacterBody2D assert(characterbody,"组件没有正确的绑定CharacterBody2D") if auto_recover_dash_count_at_ready: full_recover_dash_count() func _physics_process(delta: float) -> void: if Engine.is_editor_hint(): return #不允许Dash则直接return if not can_dash: return _update_dash(delta) characterbody.move_and_slide() func _update_dash(delta) -> void: return ##整合之后的函数,如果不需要额外的逻辑,可以直接通过这个触发Dash func integrate_dash(dash_dir: Vector2) -> bool: if not predash(dash_dir): return false await get_tree().process_frame #等待一帧 can_dash = true brust_dash() return true ##dash函数,输入一个Dash的方向,返回是否成功 func brust_dash() -> bool: var old: Vector2 = characterbody.velocity; var burst: Vector2 = _dash_direction.normalized() * dash_speed; if sign(old.x) == sign(burst.x) and abs(old.x) > abs(burst.x): burst.x = old.x characterbody.velocity = burst dash_brusted.emit() return true ##dash准备函数,需要在dash的前一帧触发 func predash(dash_dir: Vector2) -> bool: if not get_can_dash(): return false print("Dash更新中") last_dash_count = maxi(last_dash_count -1,0) _is_dashing = true _dash_direction = dash_dir return true ##停止Dash,实际上是关闭Dash标识符 func stop_dash(force_stop: bool = false) -> void: if force_stop: characterbody.velocity = Vector2.ZERO characterbody.move_and_slide() _is_dashing = false ##完全回复的Dash次数 func full_recover_dash_count() -> void: last_dash_count = maxium_dash_count ##回复指定数量的Dash次数 func recover_dash_count(recover_count : int) -> void: last_dash_count = clampi(last_dash_count+ recover_count, 0,maxium_dash_count) ##子类可以重写此方法以自定义Dash的条件 func get_can_dash() -> bool: return last_dash_count > 0