godot-plateformer/addons/reedcomponent/locomotion/jump_locomotion.gd

172 lines
6.0 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'''Agens移动控制组件
Extra:
jump() 基础的跳跃,可以往上跳跃
stop_jump() 停止跳跃
walL_jump() 墙跳
'''
class_name JumpLocomotionComponent extends LocomotionComponent
# <-- JUMP & FALL PROPOTIY -->
@export_category("Jump Properties")
##跳跃力度,在调用跳跃方法时自动处理为负,无需 * -1
@export var jump_force : float = 280
##跳跃极限时间,超过这个时间则无法继续监听跳跃输入
@export var jump_hold_maxium_time : float = .18
##跳跃时对移动输入的补正
@export var jump_horizontal_Boost : float = 80
##跳跃时对移动输入的补正
@export var jump_countinus_horizontal_Boost : float = 200
##是否持续的增加jump的水平补正如果不持续则只在跳跃的第一帧添加
@export var countinus_jump_boost: bool = true
##跳跃对移动输入的水平补正可以持续的时间
@export var jump_horizontal_Boost_last_time : float = .08
##跳跃水平方向速度补偿的最大值,如果当前速度加补偿速度超过了这个阈值,会自动重置为该阈值
@export var max_jump_horizontal_boost_speed: float = 600
##Jump时是否还需要受到重力影响
@export var jump_effected_by_gravity : bool = true
##半重力触发阈值,当速度小于这个数值时,会将角色的重力减半
@export var light_gravity_threshold: float = 80
##半重力乘量,默认.5
@export var light_gravity_mult: float = .5
@export_category("Wall Properties")
##如果apply则在墙壁下滑时会额外受到摩擦而保持wall slide speed
@export var apply_wall_slide_gravity: bool = true
##在墙壁下滑时的速度最大值
@export var wall_slide_fall_maxium_speed: float = 105
@export var wall_jump_base_force_x : float = 380
@export var wall_jump_base_force_y : float = -1
var _jump_timer : float
var _is_jumping : bool = false
var _is_wall_jumping: bool = false
var _h_boost_timer: float
##跳跃
func jump(force_reset_x: bool = false) -> bool:
if _is_jumping : return false
var input_dir = sign(_movement_input) as float
if not force_reset_x:
if input_dir != 0 :
var vel_dir := sign(characterbody.velocity.x)
var accel_dir := sign(_current_acceleration.x)
# ---------- 情况 1角色在起步 ----------
# velocity 还没起来,但已经在往某方向加速
if vel_dir == 0 and accel_dir == input_dir:
characterbody.velocity.x += input_dir * jump_horizontal_Boost
# ---------- 情况 2角色稳定同向移动 ----------
elif vel_dir == input_dir and accel_dir == 0:
characterbody.velocity.x += input_dir * jump_horizontal_Boost
# ---------- 情况 3角色正在反向 / pivot ----------
elif vel_dir == -input_dir:
characterbody.velocity.x = input_dir * jump_horizontal_Boost
apply_jump_horizontal_boost(input_dir)
else:
##如果强制重置,我们会让水平速度直接等于输入加水平补正
characterbody.velocity.x = input_dir * jump_horizontal_Boost
print("强制重置")
_jump_timer = jump_hold_maxium_time
_h_boost_timer = jump_horizontal_Boost_last_time
_is_jumping = true
characterbody.velocity.y = _get_jump_force()
return true
##停止跳跃,实际的功能是重置跳跃相关的标识符
func stop_jump() -> void:
# 如果还在上升,直接砍掉上升速度
if characterbody.velocity.y < 0 and _jump_timer > 0:
characterbody.velocity.y *= 0.6
_jump_timer = 0
_h_boost_timer = 0
_is_jumping = false
_is_wall_jumping = false
##墙跳
func wall_jump() -> void:
if not characterbody.is_on_wall_only(): return
characterbody.velocity.x = characterbody.get_wall_normal().x * wall_jump_base_force_x #基础的wall jump force
characterbody.velocity.y = _get_jump_force()
_jump_timer = jump_hold_maxium_time
_is_jumping = true
_is_wall_jumping = true
func _update_gravity(delta: float) -> void:
#if _jump_timer >= 0:
#if _is_jumping:
#characterbody.velocity.y = _get_jump_force()
#_jump_timer -= delta
#
##如果不希望jump时受到重力影响可以关闭此开关
#if not jump_effected_by_gravity: return
if _jump_timer > 0 and _is_jumping:
_jump_timer -= delta
# --------- Continuous Jump Horizontal Boost ---------
if countinus_jump_boost \
and _is_jumping \
and _h_boost_timer > 0:
_h_boost_timer -= delta
var input_dir := sign(_movement_input)
if input_dir != 0:
_apply_continuous_jump_boost(input_dir, delta)
super._update_gravity(delta)
## 应用跳跃水平补偿的后的处理逻辑
func apply_jump_horizontal_boost(input_dir: float) -> void:
var boost_vel := input_dir * jump_horizontal_Boost
var current_vel := characterbody.velocity.x
# 只处理「同方向」的情况
if sign(current_vel) == input_dir:
if abs(current_vel) > max_jump_horizontal_boost_speed:
characterbody.velocity.x = boost_vel
func _apply_continuous_jump_boost(input_dir: float, delta: float) -> void:
var current_vel := characterbody.velocity.x
var max_vel := input_dir * max_jump_horizontal_boost_speed
# 如果已经超过最大值(极少数情况),直接截断
if sign(current_vel) == input_dir and abs(current_vel) > abs(max_vel):
characterbody.velocity.x = max_vel
return
# 只有在“同方向”或“静止”时,才允许继续加速
if current_vel == 0 or sign(current_vel) == input_dir:
characterbody.velocity.x += input_dir * jump_countinus_horizontal_Boost * delta
##重写重力乘量函数
func _get_gravity_scale() -> float:
var c = absf(characterbody.velocity.y) <= light_gravity_threshold && _is_jumping
return light_gravity_mult if c else default_gravity_scale
##重写最大下落速度
func _get_max_fall_speed() -> float:
var wall_normal_x = characterbody.get_wall_normal().x
if -1 * sign(_movement_input) == wall_normal_x and characterbody.is_on_wall() and characterbody.velocity.y > 0:
return wall_slide_fall_maxium_speed
else:
return fall_maxium_speed
##设定jump的力度
func _get_jump_force() -> float:
var result: float = jump_force
if _is_wall_jumping and wall_jump_base_force_y > 0:
result = wall_jump_base_force_y
return -1.0 * result