Blobby/src/Actor/PlayerStateMachine.gd

118 lines
3.0 KiB
GDScript

extends StateMachine
# Adds the intial states
func _ready():
add_state("idle")
add_state("run")
add_state("walk")
add_state("jump")
add_state("fall")
print_debug(states)
set_state(states.idle)
# Calls the parent behaviours according to state
func _state_logic(delta):
# RayCasts for visual debugging
# TODO Global context switch for debug/build mode
# \ is for new line in multiline statements
parent.get_node("CollisionShape2D/RayCaster")._raycast(
Vector2.DOWN,
parent.get_node("CollisionShape2D").get_shape(),
parent.collision_mask
)
var handle_input_ref
match self.state:
"idle":
handle_input_ref = funcref(self, 'handle_idle_input')
"walk":
handle_input_ref = funcref(self, 'handle_walk_input')
"run":
handle_input_ref = funcref(self, 'handle_run_input')
"jump":
handle_input_ref = funcref(self, 'handle_jump_input')
"fall":
handle_input_ref = funcref(self, 'handle_fall_input')
_:
print("don't panik")
parent._velocity = handle_input_ref.call_func(delta)
parent.execute_movement()
func handle_idle_input(delta, direction := get_horizontal_direction()) -> Vector2:
if Input.is_action_pressed("boost_move"):
return parent.handle_grounded_movement(delta, direction, "run")
else:
return parent.handle_grounded_movement(delta, direction, "walk")
func handle_walk_input(delta, direction := get_horizontal_direction()) -> Vector2:
return parent.handle_grounded_movement(delta, direction, state)
func handle_run_input(delta, direction := get_horizontal_direction()) -> Vector2:
return parent.handle_grounded_movement(delta, direction, state)
func handle_jump_input(delta, direction := get_horizontal_direction()) -> Vector2:
return parent.handle_jump_movement(delta, direction)
func handle_fall_input(delta, direction := get_horizontal_direction()) -> Vector2:
return parent.handle_fall_movement(delta, direction)
func get_horizontal_direction() -> Vector2:
return Vector2(
(
Input.get_action_strength("move_right")
- Input.get_action_strength("move_left")
),
0
)
# Determines which state should be active at the moment
func _get_transition(delta):
parent.get_node("StateLable").text = (
self.state
+ " x vel:"
+ String(round(parent._velocity.x))
)
var new_state
# TODO Can get stuck in Fall on ledges
if ! parent.is_on_floor():
if parent._velocity.y < 0:
new_state = states.jump
if parent._velocity.y >= 0:
# if self.state == states.run:
# parent._velocity.y = 0
new_state = states.fall
elif parent._velocity.x != 0:
if Input.is_action_pressed("boost_move"):
new_state = states.run
else:
new_state = states.walk
else:
# TODO How does this apply to enviornment induced movement?
new_state = states.idle
if new_state != self.state:
return new_state
parent.init_boost = false
return null
func _enter_state(new_state, old_state):
if new_state == "run" || "walk":
parent.init_boost = true
if old_state == "run" && new_state == "walk":
parent.init_boost = false
func _exit_state(old_state, new_state):
pass