class_name Player extends CharacterBody2D @onready var sprite := $Sprite as AnimatedSprite2D @onready var audio_player := $AudioPlayer as AudioStreamPlayer signal state_change(old: States, new: States) enum States {IDLE, RUN_START, RUN, ROLL, JUMP_START, JUMP, FALL, LAND, DAMAGE, RAGDOLL, BOUNCE, LAY, SHOOT, JAB, STRAIGHT, KICK, POUND} const STATES_IMMOBILE = [States.ROLL, States.DAMAGE, States.RAGDOLL, States.BOUNCE, States.LAY, States.SHOOT, States.JAB, States.STRAIGHT, States.KICK, States.POUND] const STATES_AIRBORNE = [States.JUMP_START, States.JUMP, States.FALL] const ROLL_DUST = preload("uid://botc600n5fcgt") const JUMP_DUST = preload("uid://c4h1cj75b5sry") const JUMP_SOUND = preload("uid://d1hwunwdel6sy") const HIT_GROUND = preload("uid://ciglwfq0vua8i") const SPEED = 90.0 const ACCEL = 450 const JUMP_VELOCITY = -312.0 const ROLL_VELOCITY = 150.0 const ROLL_DECEL = 1080 # Get the gravity from the project settings to be synced with RigidBody nodes. var gravity = ProjectSettings.get_setting("physics/2d/default_gravity") var state: States = States.IDLE: set = _set_state var direction: float var grounded: bool var running: bool var rolling: bool var ragdoll: bool var bounce: bool var lay: bool var shooting: bool var melee: bool func _set_state(s: States): state_change.emit(state, s) state = s func _process(_delta: float) -> void: $State.text = States.keys()[state] func _physics_process(delta): # Add the gravity. if not is_on_floor(): velocity.y += gravity * delta # Jumping if state not in STATES_IMMOBILE and state not in STATES_AIRBORNE and Input.is_action_just_pressed("jump") and is_on_floor(): state = States.JUMP_START audio_player.stream = JUMP_SOUND audio_player.play() var jump_dust = JUMP_DUST.instantiate() jump_dust.position = position add_sibling(jump_dust) velocity.y = JUMP_VELOCITY # Short hops if Input.is_action_just_released("jump") && !is_on_floor(): velocity.y = velocity.y / 2 # Falling if state not in [States.ROLL, States.RAGDOLL, States.BOUNCE] and velocity.y > 0: state = States.FALL if state in [States.FALL] and is_zero_approx(velocity.y): if direction: state = States.RUN else: state = States.LAND # Rolls if state not in STATES_IMMOBILE and state != States.ROLL and \ (Input.is_action_just_pressed("roll_jump") or Input.is_action_just_pressed("roll")): state = States.ROLL if is_on_floor(): var roll_dust = ROLL_DUST.instantiate() roll_dust.position = position roll_dust.flip_h = !sprite.flip_h add_sibling(roll_dust) if !sprite.flip_h: velocity.x = ROLL_VELOCITY else: velocity.x = -ROLL_VELOCITY if velocity.y >= 0 && Input.is_action_just_pressed("roll_jump"): velocity.y = -120 # Melee if state not in STATES_IMMOBILE and Input.is_action_just_pressed("melee"): state = States.MELEE if Input.is_action_pressed("roll"): # Pound pass # Shooting if state not in STATES_IMMOBILE and Input.is_action_just_pressed("shoot"): state = States.SHOOT match global.save.projectile: global.save.Projectile.BLAST: pass # Ragdoll if state not in [States.RAGDOLL, States.BOUNCE, States.LAY] and Input.is_action_just_pressed("ragdoll"): state = States.RAGDOLL if state in [States.RAGDOLL] and is_on_floor(): state = States.BOUNCE var roll_dust = ROLL_DUST.instantiate() roll_dust.position = position roll_dust.flip_h = !sprite.flip_h add_sibling(roll_dust) velocity.y = -120 audio_player.stream = HIT_GROUND audio_player.play() if state in [States.BOUNCE] and is_on_floor() and velocity.y >= 0: state = States.LAY audio_player.stream = HIT_GROUND audio_player.play() if state in [States.LAY] and is_on_floor(): velocity.x = move_toward(velocity.x, 0, ACCEL * delta) # Overall physics direction = Input.get_axis("move_left", "move_right") if state == States.ROLL and sprite.frame > 7: # Slow down if in the later roll frames. velocity.x = move_toward(velocity.x, 0, ROLL_DECEL * delta) elif state not in [States.ROLL, States.DAMAGE, States.RAGDOLL, States.BOUNCE, States.LAY, States.SHOOT, States.MELEE]: # Apply velocity changes if not in a restricted movement state. velocity.x = move_toward(velocity.x, direction * SPEED, ACCEL * delta) if direction: if state not in [States.JUMP_START, States.JUMP, States.FALL, States.RUN_START, States.RUN]: state = States.RUN_START else: if state not in [States.JUMP_START, States.JUMP, States.FALL, States.LAND]: state = States.IDLE move_and_slide()