229 lines
5.7 KiB
GDScript
229 lines
5.7 KiB
GDScript
extends Node
|
|
|
|
|
|
enum MovementType {
|
|
PLATFORMER,
|
|
TOP_DOWN,
|
|
CUSTOM,
|
|
NONE
|
|
}
|
|
enum DashType {
|
|
KEYS,
|
|
HORIZONTAL_KEYS,
|
|
MOUSE,
|
|
CONTINOUS_MOUSE,
|
|
SPRINT,
|
|
NONE
|
|
}
|
|
|
|
|
|
class CharMovement:
|
|
var movement_type: MovementType
|
|
var custom_movement_func: Callable = Callable()
|
|
|
|
# EXTRA (that may or may not be added)
|
|
# Coyote time
|
|
# Input buffer
|
|
|
|
# Params
|
|
var speed: float
|
|
var sprint_speed: float
|
|
var jump_power: float
|
|
var extra_jumps: int
|
|
var coyote_time: float
|
|
var jump_buffer_time: float
|
|
var dash_type: DashType
|
|
var aerial_dash_count: int
|
|
var vel_multiplier_after_dash: float
|
|
var dash_speed: float
|
|
var dash_dur: float
|
|
var dash_cd: float
|
|
# Physics Params
|
|
var gravity: float
|
|
var terminal_vel: float
|
|
|
|
# Updating
|
|
var velocity: Vector2 = Vector2.ZERO
|
|
|
|
var is_grounded: bool = false
|
|
|
|
var can_jump: bool = true
|
|
var can_move: bool = true
|
|
|
|
var jumps: int = 0
|
|
var coyote_timer: float = 0.0
|
|
var jump_buffer_timer: float = 0.0
|
|
|
|
var is_dashing: bool = false
|
|
var is_dash_cd: bool = false
|
|
var dash_timer: float = 0.0
|
|
var dash_cd_timer: float = 0.0
|
|
var aerial_dashes: int = 0
|
|
|
|
var look_dir: Vector2 = Vector2.ZERO
|
|
var last_look_dir: Vector2 = Vector2.ZERO
|
|
var move_dir: Vector2 = Vector2.ZERO
|
|
var move_dir_x: float = 0.0
|
|
var last_move_dir: Vector2 = Vector2.ZERO
|
|
var last_move_dir_x: float = 0.0
|
|
var was_dash_pressed: bool = false
|
|
var was_jump_pressed: bool = false
|
|
var is_jump_held: bool = false
|
|
|
|
func _init(
|
|
_movement_type: MovementType,
|
|
_speed: float,
|
|
_sprint_speed: float,
|
|
_jump_power: float,
|
|
_extra_jumps: int,
|
|
_coyote_time: float,
|
|
_jump_buffer_time: float,
|
|
_dash_type: DashType,
|
|
_aerial_dash_count: int,
|
|
_vel_multiplier_after_dash: float,
|
|
_dash_speed: float,
|
|
_dash_dur: float,
|
|
_dash_cd: float,
|
|
_gravity: float,
|
|
_terminal_vel: float
|
|
):
|
|
movement_type = _movement_type
|
|
speed = _speed
|
|
sprint_speed = _sprint_speed
|
|
jump_power = _jump_power
|
|
extra_jumps = _extra_jumps
|
|
coyote_time = _coyote_time
|
|
dash_type = _dash_type
|
|
dash_speed = _dash_speed
|
|
dash_dur = _dash_dur
|
|
dash_cd = _dash_cd
|
|
gravity = _gravity
|
|
terminal_vel = _terminal_vel
|
|
|
|
# Long names
|
|
jump_buffer_time = _jump_buffer_time
|
|
aerial_dash_count = _aerial_dash_count
|
|
vel_multiplier_after_dash = _vel_multiplier_after_dash
|
|
|
|
func set_custom_movement_func(function: Callable):
|
|
custom_movement_func = function
|
|
|
|
|
|
func process(_look_dir: Vector2, _delta: float):
|
|
look_dir = _look_dir
|
|
|
|
move_dir = Input.get_vector("left", "right", "up", "down")
|
|
move_dir_x = Input.get_axis("left", "right")
|
|
was_dash_pressed = Input.is_action_just_pressed("dash")
|
|
was_jump_pressed = Input.is_action_just_pressed("jump")
|
|
is_jump_held = Input.is_action_pressed("jump")
|
|
|
|
if movement_type == MovementType.PLATFORMER:
|
|
was_jump_pressed = was_jump_pressed || Input.is_action_just_pressed("jump_alt")
|
|
is_jump_held = is_jump_held || Input.is_action_pressed("jump_alt")
|
|
|
|
func phys_process(delta: float):
|
|
move_logic(delta)
|
|
jump_logic(delta)
|
|
# dash overrides other movement
|
|
dash_logic(delta)
|
|
|
|
physics(delta)
|
|
|
|
|
|
func dash_logic(delta: float):
|
|
if is_grounded: aerial_dashes = 0
|
|
|
|
if was_dash_pressed && !is_dashing && !is_dash_cd:
|
|
if movement_type == MovementType.TOP_DOWN \
|
|
|| aerial_dashes < aerial_dash_count \
|
|
|| is_grounded:
|
|
is_dashing = true
|
|
last_look_dir = look_dir
|
|
last_move_dir = move_dir
|
|
last_move_dir_x = move_dir_x
|
|
aerial_dashes += 1
|
|
|
|
if is_dashing:
|
|
dash_timer += delta
|
|
dash_velocity(delta)
|
|
|
|
if dash_timer >= dash_dur:
|
|
is_dashing = false
|
|
is_dash_cd = true
|
|
dash_timer = 0.0
|
|
velocity *= vel_multiplier_after_dash
|
|
|
|
if is_dash_cd:
|
|
dash_cd_timer += delta
|
|
|
|
if dash_cd_timer >= dash_cd:
|
|
is_dash_cd = false
|
|
dash_cd_timer = 0.0
|
|
|
|
func dash_velocity(delta: float):
|
|
match dash_type:
|
|
DashType.KEYS: velocity = last_move_dir * dash_speed * delta
|
|
DashType.HORIZONTAL_KEYS: velocity.x = last_move_dir_x * dash_speed * delta
|
|
DashType.MOUSE: velocity = last_look_dir * dash_speed * delta
|
|
DashType.CONTINOUS_MOUSE: velocity = look_dir * dash_speed * delta
|
|
DashType.SPRINT: pass
|
|
DashType.NONE: pass
|
|
|
|
|
|
func move_logic(delta: float):
|
|
if can_move: movement_velocity(delta)
|
|
|
|
func movement_velocity(delta: float):
|
|
var final_speed = speed
|
|
if dash_type == DashType.SPRINT && Input.is_action_pressed("dash"):
|
|
final_speed = sprint_speed
|
|
|
|
match movement_type:
|
|
MovementType.TOP_DOWN: velocity = move_dir * final_speed * delta
|
|
MovementType.PLATFORMER: velocity.x = move_dir_x * final_speed * delta
|
|
MovementType.CUSTOM: custom_movement_func.call(delta)
|
|
MovementType.NONE: pass
|
|
|
|
|
|
func jump_logic(delta: float):
|
|
if is_grounded: jumps = 0
|
|
|
|
if !can_jump || movement_type != MovementType.PLATFORMER: return
|
|
|
|
# Spaghetti restaurant: $0.0 for 1 spaghett
|
|
if is_grounded && was_jump_pressed: jump()
|
|
elif coyote_timer < coyote_time \
|
|
&& was_jump_pressed && jumps == 0: jump()
|
|
elif jumps <= extra_jumps \
|
|
&& !is_grounded && was_jump_pressed: jump()
|
|
elif is_jump_held && is_grounded \
|
|
&& jump_buffer_timer < jump_buffer_time:
|
|
jumps = 0; jump()
|
|
|
|
if !is_grounded \
|
|
&& coyote_timer < coyote_time:
|
|
coyote_timer += delta
|
|
|
|
if is_jump_held && !is_grounded \
|
|
&& jump_buffer_timer < jump_buffer_time:
|
|
jump_buffer_timer += delta
|
|
|
|
if is_grounded:
|
|
coyote_timer = 0.0
|
|
if !is_jump_held: jump_buffer_timer = 0.0
|
|
|
|
func jump():
|
|
velocity.y = jump_power * -1.0
|
|
jumps += 1
|
|
|
|
|
|
func physics(delta: float):
|
|
if movement_type != MovementType.PLATFORMER: return
|
|
|
|
if !is_grounded:
|
|
velocity.y += gravity * delta
|
|
velocity.y = min(velocity.y, terminal_vel * delta)
|
|
else:
|
|
velocity.y = min(0, velocity.y)
|