Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extends CharacterBody2D
- @onready var animation_sprite = $AnimatedSprite2D
- @onready var last_facing_direction = 1 # Default direction to right
- @onready var roll_timer = $roll_timer # Timer for roll duration
- @onready var roll_cooldown_timer = $roll_cooldown_timer # Timer for roll cooldown (set `wait_time` to 2.0 seconds)
- @onready var death_timer: Timer = $death_timer
- const speed = 125 # Normal speed
- const roll_speed = 250 # Roll speed
- const gravity = 10
- const jump_power = -225
- var dir
- var roll_direction = 1 # Initialize roll direction
- var main_sm: LimboHSM
- func _ready():
- add_to_group("Player")
- initiate_state_machine()
- func _physics_process(_delta: float) -> void:
- if main_sm.get_active_state().name == "die":
- return # Skip physics processing if in die state
- dir = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
- if main_sm.get_active_state().name != "roll": # Prevent movement while rolling as well
- if dir:
- velocity.x = dir * speed
- last_facing_direction = dir # Update last facing direction when moving
- else:
- velocity.x = move_toward(velocity.x, 0, speed)
- velocity.y += gravity
- flip_sprite(dir)
- move_and_slide()
- @warning_ignore("shadowed_variable")
- func flip_sprite(dir):
- if dir == 1:
- animation_sprite.flip_h = false
- elif dir == -1:
- animation_sprite.flip_h = true
- func _unhandled_input(event):
- if event.is_action_pressed("jump"):
- main_sm.dispatch(&"to_jump")
- elif event.is_action_pressed("roll") and roll_cooldown_timer.time_left == 0: # Allow roll only if cooldown has ended
- main_sm.dispatch(&"to_roll")
- func initiate_state_machine():
- main_sm = LimboHSM.new()
- add_child(main_sm)
- var idle_state = LimboState.new().named("idle").call_on_enter(idle_start).call_on_update(idle_update)
- var run_state = LimboState.new().named("run").call_on_enter(run_start).call_on_update(run_update)
- var die_state = LimboState.new().named("die").call_on_enter(die_start).call_on_update(die_update)
- var jump_state = LimboState.new().named("jump").call_on_enter(jump_start).call_on_update(jump_update)
- var roll_state = LimboState.new().named("roll").call_on_enter(roll_start).call_on_update(roll_update)
- main_sm.add_child(idle_state)
- main_sm.add_child(run_state)
- main_sm.add_child(die_state)
- main_sm.add_child(jump_state)
- main_sm.add_child(roll_state)
- main_sm.initial_state = idle_state
- main_sm.add_transition(idle_state, run_state, &"to_run")
- main_sm.add_transition(main_sm.ANYSTATE, idle_state, &"state_ended")
- main_sm.add_transition(idle_state, jump_state, &"to_jump")
- main_sm.add_transition(run_state, jump_state, &"to_jump")
- main_sm.add_transition(roll_state, jump_state, &"to_jump")
- main_sm.add_transition(main_sm.ANYSTATE, die_state, &"player_die")
- main_sm.add_transition(idle_state, roll_state, &"to_roll")
- main_sm.add_transition(run_state, roll_state, &"to_roll")
- main_sm.initialize(self)
- main_sm.set_active(true)
- func idle_start():
- animation_sprite.play("idle")
- func idle_update(_delta: float):
- if velocity.x != 0:
- main_sm.dispatch(&"to_run")
- func run_start():
- animation_sprite.play("run")
- func run_update(_delta: float):
- if velocity.x == 0:
- main_sm.dispatch(&"state_ended")
- func jump_start():
- if is_on_floor():
- animation_sprite.play("jump")
- velocity.y = jump_power
- else:
- main_sm.dispatch(&"state_ended")
- func jump_update(_delta: float):
- if is_on_floor():
- main_sm.dispatch(&"state_ended")
- # Roll State - Handles roll animation, movement, and timing
- func roll_start():
- if roll_cooldown_timer.time_left == 0: # Start roll if cooldown has ended
- roll_direction = dir if dir != 0 else last_facing_direction
- velocity.x = roll_direction * roll_speed # Apply roll speed in current facing direction
- roll_timer.start() # Start timer for roll duration
- roll_cooldown_timer.start() # Start cooldown timer for roll
- animation_sprite.play("roll") # Play roll animation
- func roll_update(_delta: float):
- # Check if the player is still on the floor
- if is_on_floor():
- # Keep rolling in the last facing direction
- velocity.x = roll_direction * roll_speed
- else:
- # If player rolls off the edge, stop the roll and let gravity take effect
- main_sm.dispatch(&"state_ended")
- # Called when roll timer ends
- func _on_roll_timer_timeout() -> void:
- main_sm.dispatch(&"state_ended") # Transition back to idle or other state
- # Die function to handle death when colliding with Killzone
- func die():
- main_sm.dispatch(&"player_die")
- # Die state - Handles death animation, time scale, and scene reload
- func die_start():
- animation_sprite.play("die")
- animation_sprite.flip_h = (last_facing_direction == -1) # Flip animation based on last direction
- Engine.time_scale = 0.5 # Slow down time
- death_timer.start(1.0) # Start death timer for 1 second
- velocity = Vector2.ZERO
- func die_update(_delta: float) -> void:
- pass # Your existing logic here, if any
- # Called when death_timer ends
- func _on_death_timer_timeout() -> void:
- Engine.time_scale = 1 # Reset time scale to normal
- get_tree().reload_current_scene() # Reload the current scene
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement