feat: implement player movement controller and state machine with dash, slide, and wall-run mechanics
This commit is contained in:
@@ -6,11 +6,15 @@ var params: MovementParams:
|
||||
get: return machine.params
|
||||
|
||||
var elapsed: float = 0.0
|
||||
var stamina: float = 0.0
|
||||
|
||||
|
||||
func enter(_data: Dictionary = {}) -> void:
|
||||
elapsed = 0.0
|
||||
stamina = params.wall_cling_max_stamina
|
||||
machine.register_chain_mechanic("wall_cling")
|
||||
# Kill most velocity but keep slight downward
|
||||
machine.player.velocity = Vector3.ZERO
|
||||
|
||||
|
||||
func exit() -> void:
|
||||
@@ -19,34 +23,56 @@ func exit() -> void:
|
||||
|
||||
func update(delta: float) -> void:
|
||||
elapsed += delta
|
||||
var vel: Vector3 = machine.player.velocity
|
||||
vel.x = params.wall_cling_horizontal_speed
|
||||
vel.y = params.wall_cling_vertical_speed
|
||||
vel.z = params.wall_cling_horizontal_speed
|
||||
machine.player.velocity = vel
|
||||
machine.player.move_and_slide()
|
||||
stamina -= params.wall_cling_stamina_drain * delta
|
||||
|
||||
# Jump off wall
|
||||
var player := machine.player
|
||||
var vel: Vector3 = player.velocity
|
||||
|
||||
# ── Slow slide down ───────────────────────────────────────────────────
|
||||
var slide_factor := 1.0 - (stamina / params.wall_cling_max_stamina) # 0→1 as stamina drains
|
||||
vel.x = 0.0
|
||||
vel.z = 0.0
|
||||
vel.y = params.wall_cling_slide_speed * (1.0 + slide_factor * 2.0)
|
||||
|
||||
# Push into wall to maintain contact
|
||||
vel -= machine.wall_normal * 1.0
|
||||
|
||||
player.velocity = vel
|
||||
player.move_and_slide()
|
||||
|
||||
# ── Stamina depleted → fall ───────────────────────────────────────────
|
||||
if stamina <= 0.0:
|
||||
machine.wall_normal = Vector3.ZERO
|
||||
machine.wall_side = 0.0
|
||||
machine.switch_to("air")
|
||||
return
|
||||
|
||||
# ── Jump off wall ─────────────────────────────────────────────────────
|
||||
if machine.input_jump_just_pressed:
|
||||
var push_dir := machine.wall_normal * params.wall_run_jump_off_normal
|
||||
var vel2 := Vector3(push_dir.x, params.jump_velocity, push_dir.z)
|
||||
machine.player.velocity = vel2
|
||||
player.velocity = Vector3(push_dir.x, params.jump_velocity, push_dir.z)
|
||||
machine.wall_normal = Vector3.ZERO
|
||||
machine.wall_side = 0.0
|
||||
machine.register_chain_mechanic("wall_cling_jump")
|
||||
machine.switch_to("air")
|
||||
return
|
||||
|
||||
# Re-enter wall run with input
|
||||
# ── Re-enter wall run with movement input ─────────────────────────────
|
||||
if machine.input_dir.length() > 0.1:
|
||||
machine.switch_to("wall_run")
|
||||
return
|
||||
|
||||
# Fall
|
||||
if not machine.wall_normal or machine.wall_normal.is_zero_approx():
|
||||
# ── Lost wall contact ─────────────────────────────────────────────────
|
||||
var wall := machine.detect_wall_horizontal()
|
||||
if wall == Vector3.ZERO:
|
||||
machine.wall_normal = Vector3.ZERO
|
||||
machine.wall_side = 0.0
|
||||
machine.switch_to("air")
|
||||
return
|
||||
|
||||
if machine.player.is_on_floor():
|
||||
# ── Hit floor ─────────────────────────────────────────────────────────
|
||||
if player.is_on_floor():
|
||||
machine.on_ground = true
|
||||
machine.wall_normal = Vector3.ZERO
|
||||
machine.register_chain_mechanic("cling_land")
|
||||
machine.wall_side = 0.0
|
||||
machine.switch_to("ground")
|
||||
|
||||
Reference in New Issue
Block a user