134 lines
3.6 KiB
GDScript
134 lines
3.6 KiB
GDScript
class_name Character
|
|
extends CharacterBody2D
|
|
|
|
const GRAVITY := 1200.0
|
|
|
|
@export var speed := 180.0
|
|
@export var jump_intensity := 304.056
|
|
@export var attack_duration := 0.4
|
|
@export var attack_lunge_duration := 0.18
|
|
@export var attack_lunge_speed := 220.0
|
|
@export var air_attack_duration := 0.45
|
|
@export var air_attack_lunge_duration := 0.22
|
|
@export var air_attack_lunge_speed := 260.0
|
|
|
|
@onready var animation_player: AnimationPlayer = $AnimationPlayer
|
|
@onready var character_sprite: Sprite2D = $CharacterSprite
|
|
|
|
enum State { IDLE, WALK, JUMP, LAND, ATTACK, AIR_ATTACK }
|
|
|
|
var anim_map := {
|
|
State.IDLE: "warrior_idle",
|
|
State.WALK: "warrior_idle",
|
|
State.JUMP: "warrior_w",
|
|
State.LAND: "warrior_idle",
|
|
State.ATTACK: "warrior_a",
|
|
State.AIR_ATTACK: "warrior_a",
|
|
}
|
|
var attack_direction := Vector2.RIGHT
|
|
var attack_lunge_time_left := 0.0
|
|
var attack_time_left := 0.0
|
|
var heading := Vector2.RIGHT
|
|
var height := 0.0
|
|
var height_speed := 0.0
|
|
var state := State.IDLE
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
handle_input()
|
|
handle_air_time(delta)
|
|
handle_attack_time(delta)
|
|
handle_movement()
|
|
handle_animations()
|
|
set_sprite_height_position()
|
|
set_heading()
|
|
flip_sprites()
|
|
move_and_slide()
|
|
|
|
func handle_input() -> void:
|
|
pass
|
|
|
|
func handle_air_time(delta: float) -> void:
|
|
if state != State.JUMP:
|
|
return
|
|
height += height_speed * delta
|
|
if height <= 0.0 and height_speed < 0.0:
|
|
height = 0.0
|
|
height_speed = 0.0
|
|
state = State.LAND
|
|
else:
|
|
height_speed -= GRAVITY * delta
|
|
|
|
func handle_attack_time(delta: float) -> void:
|
|
if state != State.ATTACK and state != State.AIR_ATTACK:
|
|
return
|
|
velocity.y = 0.0
|
|
attack_time_left -= delta
|
|
if attack_time_left <= 0.0:
|
|
state = State.IDLE
|
|
velocity = Vector2.ZERO
|
|
return
|
|
attack_lunge_time_left -= delta
|
|
if attack_lunge_time_left <= 0.0:
|
|
velocity.x = 0.0
|
|
|
|
func handle_movement() -> void:
|
|
if state == State.JUMP or state == State.ATTACK or state == State.AIR_ATTACK:
|
|
return
|
|
if absf(velocity.x) > 0.0:
|
|
state = State.WALK
|
|
else:
|
|
state = State.IDLE
|
|
if state == State.LAND:
|
|
state = State.IDLE
|
|
|
|
func handle_animations() -> void:
|
|
var animation_name: String = anim_map[state]
|
|
if animation_player.has_animation(animation_name) and animation_player.current_animation != animation_name:
|
|
animation_player.play(animation_name)
|
|
|
|
func set_sprite_height_position() -> void:
|
|
character_sprite.position = Vector2.UP * height
|
|
|
|
func set_heading() -> void:
|
|
pass
|
|
|
|
func flip_sprites() -> void:
|
|
character_sprite.flip_h = heading == Vector2.LEFT
|
|
|
|
func can_jump() -> bool:
|
|
return state == State.IDLE or state == State.WALK
|
|
|
|
func can_attack() -> bool:
|
|
return state == State.IDLE or state == State.WALK
|
|
|
|
func can_air_attack() -> bool:
|
|
return state == State.IDLE or state == State.WALK
|
|
|
|
func start_jump() -> void:
|
|
state = State.JUMP
|
|
height_speed = jump_intensity
|
|
|
|
func start_attack() -> void:
|
|
start_directional_attack(heading)
|
|
|
|
func start_directional_attack(direction: Vector2) -> void:
|
|
var attack_x := -1.0 if direction.x < 0.0 else 1.0
|
|
attack_direction = Vector2(attack_x, 0.0)
|
|
heading = Vector2.RIGHT if attack_x > 0.0 else Vector2.LEFT
|
|
state = State.ATTACK
|
|
attack_time_left = attack_duration
|
|
attack_lunge_time_left = attack_lunge_duration
|
|
velocity = Vector2(attack_x * attack_lunge_speed, 0.0)
|
|
|
|
func start_air_attack() -> void:
|
|
start_directional_air_attack(heading)
|
|
|
|
func start_directional_air_attack(direction: Vector2) -> void:
|
|
var attack_x := -1.0 if direction.x < 0.0 else 1.0
|
|
attack_direction = Vector2(attack_x, 0.0)
|
|
heading = Vector2.RIGHT if attack_x > 0.0 else Vector2.LEFT
|
|
state = State.AIR_ATTACK
|
|
attack_time_left = air_attack_duration
|
|
attack_lunge_time_left = air_attack_lunge_duration
|
|
velocity = Vector2(attack_x * air_attack_lunge_speed, 0.0)
|