114 lines
3.1 KiB
GDScript3
114 lines
3.1 KiB
GDScript3
|
|
'''冲刺控制组件
|
|||
|
|
注:该组件只适用于继承自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
|