class_name Player extends CharacterBody2D const SPEED: int = 1000 @onready var animated_sprite: AnimatedSprite2D = $AnimatedSprite2D @onready var fight_animation: AnimatedSprite2D = $FightAnimation @onready var cam: Camera2D = $Camera2D @onready var raycast: RayCast2D = $RayCast2D @onready var cursor_hide_timer: Timer = $CursorHideTimer const RAYCAST_RANGE: int = 22 @export var tilemap: TileMapLayer var tilesize: int = 32 var position_limit_rect: Rect2 const STILL_POSITIONS: Array[String] = ["sit_down", "sit_side", "hand_down", "hand_side", "hand_up"] var health: int = 10 var damage: int = 2 func _ready() -> void: EventManager.player = self var used_tilemap_rect: Rect2i = tilemap.get_used_rect() tilesize = tilemap.tile_set.tile_size.x cam.limit_left = used_tilemap_rect.position.x * tilesize cam.limit_top = used_tilemap_rect.position.y * tilesize cam.limit_right = used_tilemap_rect.end.x * tilesize cam.limit_bottom = used_tilemap_rect.end.y * tilesize var margin: float = float(tilesize) / 4 position_limit_rect = Rect2( Vector2(cam.limit_left + margin, cam.limit_top - margin), Vector2( (cam.limit_right - margin) - (cam.limit_left + margin), (cam.limit_bottom - margin / 2) - (cam.limit_top + margin / 2) ) ) func _process(_delta: float) -> void: if EventManager.player_free && !EventManager.animation_player.is_playing() && Input.is_action_just_pressed("interact"): interact() func interact() -> void: var interactable: Interactable if raycast.is_colliding() && raycast.get_collider() is Interactable: interactable = raycast.get_collider() else: interactable = null var fightable: Fightable if raycast.is_colliding() && raycast.get_collider() is Fightable: fightable = raycast.get_collider() else: fightable = null match animated_sprite.animation: "down": animated_sprite.play("hand_down") if interactable == null: fight_animation.rotation_degrees = 0 fight_animation.play() if !fight_animation.is_playing(): fight_animation.play() await animated_sprite.animation_finished animated_sprite.animation = "down" "up": animated_sprite.play("hand_up") if interactable == null: fight_animation.rotation_degrees = 180 fight_animation.play() if !fight_animation.is_playing(): fight_animation.play() await animated_sprite.animation_finished animated_sprite.animation = "up" "side": animated_sprite.play("hand_side") if interactable == null: if animated_sprite.flip_h: fight_animation.rotation_degrees = 90 else: fight_animation.rotation_degrees = -90 if !fight_animation.is_playing(): fight_animation.play() await animated_sprite.animation_finished animated_sprite.animation = "side" if interactable != null: interactable.interact(self) elif fightable != null: fightable.fight(self) func _physics_process(delta: float) -> void: if !STILL_POSITIONS.has(animated_sprite.animation) && EventManager.player_free && !EventManager.animation_player.is_playing(): var input := Input.get_vector("move_left", "move_right", "move_up", "move_down").normalized() var raycast_input := Vector2.ZERO if abs(input.x) > abs(input.y): raycast_input.x = sign(input.x) elif abs(input.y) > 0: raycast_input.y = sign(input.y) if raycast_input != Vector2.ZERO: raycast.target_position = raycast_input * RAYCAST_RANGE velocity = input * delta * SPEED * 3 move_and_slide() position = position.clamp(position_limit_rect.position, position_limit_rect.end) if velocity.length() != 0: animated_sprite.play() animated_sprite.flip_h = false if abs(velocity.x) > abs(velocity.y): animated_sprite.animation = "side" animated_sprite.flip_h = velocity.x < 0 elif velocity.y < 0: animated_sprite.animation = "up" else: animated_sprite.animation = "down" else: animated_sprite.stop() func _unhandled_input(event: InputEvent) -> void: if event is InputEventMouse: cursor_hide_timer.stop() Input.mouse_mode = Input.MOUSE_MODE_VISIBLE elif EventManager.player_free && !EventManager.animation_player.is_playing() && !event.is_action("escape"): if cursor_hide_timer.is_stopped(): cursor_hide_timer.start() await cursor_hide_timer.timeout Input.mouse_mode = Input.MOUSE_MODE_HIDDEN