class_name Player extends Entity @export var GRAVITY = 30 @export var JUMP_FORCE = 500 @onready var animated_sprite = $AnimatedSprite2D @onready var attack_timer = $AttackTimer @onready var collider = $CollisionShape2D @onready var punch_hitbox = $PunchHitbox @onready var death_timer = $DeathTimer @onready var player_hurt_sfx = $PlayerHurtSfx @onready var player_death_sfx = $PlayerDeathSfx @onready var hurt_timer = $HurtTimer @onready var health_bar = $HealthBar @onready var punch_vfx = $PunchHitbox/AnimatedSprite2D var jumping = false var facing_right = true var right_punch = false var hurting = false var is_dying = false var is_death_sfx = false const ATTACK_DAMAGE = 20 const INITIAL_HEALTH = 50 const SPEED_MULTIPLIER = 300 const ATTACK_KNOCKBACK = 5000 func _init() -> void: super._init(INITIAL_HEALTH, SPEED_MULTIPLIER, ATTACK_DAMAGE) func _ready(): animated_sprite.play("idle") punch_hitbox.body_entered.connect(punch_connect) punch_hitbox.visible = false func _physics_process(delta): if is_on_floor(): # allow the player to jump if jumping: jumping = false if Input.is_action_just_pressed("jump"): velocity.y = -JUMP_FORCE jumping = true animated_sprite.play("jump") else: # apply gravity velocity.y += GRAVITY if velocity.y > 1000: velocity.y = 1000 if is_dying and !player_death_sfx.playing: player_death_sfx.play() elif hurting and !player_hurt_sfx.playing and death_timer.is_stopped(): player_hurt_sfx.play() # perform horizontal movement var horizontal_direction = Input.get_axis("move_left", "move_right") velocity.x = speed * horizontal_direction move_and_slide() # ensure the player faces the correct direction if horizontal_direction > 0 && !facing_right: animated_sprite.flip_h = false punch_hitbox.rotate(PI) elif horizontal_direction < 0 && facing_right: animated_sprite.flip_h = true punch_hitbox.rotate(PI) if horizontal_direction != 0: facing_right = horizontal_direction > 0 super._physics_process(delta) punch_hitbox.visible = true if !attack_timer.is_stopped() else false func punch_connect(node: Node): if node is Entity and node != self and !attack_timer.is_stopped(): node.health -= damage node.take_knockback(ATTACK_KNOCKBACK) if node.has_method("hurt_anim"): node.call("hurt_anim") func hurt_anim(): hurting = true hurt_timer.start() func _process(delta: float) -> void: if health <= 0: is_dying = true death_timer.start() health = 99999 if is_dying: animated_sprite.play("death") punch_hitbox.visible = false speed = 0 # Reset to start on death if death_timer.is_stopped(): get_tree().change_scene_to_file("res://MainMenu.tscn") if attack_timer.is_stopped() and Input.is_action_just_pressed("attack"): attack_timer.start() punch_vfx.play("default") if is_on_floor(): animated_sprite.play("Right" if right_punch else "Left") right_punch = !right_punch else: animated_sprite.play("slam") elif attack_timer.is_stopped() and !hurting and !is_dying and !jumping: var horizontal_direction = Input.get_axis("move_left", "move_right") if is_on_floor() && horizontal_direction != 0: animated_sprite.play("walk") else: animated_sprite.play("idle") if !hurt_timer.is_stopped(): animated_sprite.play("hurt") else: hurting = false var health_percentage = health * 100 / INITIAL_HEALTH if is_dying: health_bar.play("0") elif health_percentage > 80: health_bar.play("100") elif health_percentage > 60: health_bar.play("80") elif health_percentage > 40: health_bar.play("40") elif health_percentage > 20: health_bar.play("20")