172 lines
5 KiB
GDScript
172 lines
5 KiB
GDScript
class_name Player extends CharacterBody2D
|
|
|
|
@export var move_speed : float = 50.0;
|
|
|
|
var heart_attack : PackedScene = preload("res://scenes/hearts.tscn")
|
|
var scithe_attack : PackedScene = preload("res://scenes/scithe_attack.tscn")
|
|
var spit_attack : PackedScene = preload("res://scenes/spit.tscn")
|
|
var death_explosion := preload("res://scenes/player_explosion.tscn")
|
|
|
|
var dash := false
|
|
var dash_base_cd = 0.7
|
|
var dash_cd = 0
|
|
var health = 3
|
|
var mask_start_time = 10
|
|
var mask_time_remaining = 15
|
|
|
|
var charge : float = 0.0
|
|
@export var charge_time : float = 0.5
|
|
@onready var sprite = $AnimatedSprite2D
|
|
|
|
const INTERACT_DIST = 60.0
|
|
var current_mask : Types.mask_types = Types.mask_types.Melee
|
|
|
|
var last_mask : MaskDrop
|
|
var closest_mask : MaskDrop
|
|
|
|
func _ready() -> void:
|
|
EventBus.health_changed.emit(health)
|
|
|
|
func _check_items():
|
|
var masks = get_tree().get_nodes_in_group("mask")
|
|
closest_mask = null
|
|
var min_dist = INF
|
|
|
|
for mask in masks:
|
|
var dist = global_position.distance_to(mask.global_position)
|
|
if dist < INTERACT_DIST + 10:
|
|
min_dist = dist
|
|
closest_mask = mask
|
|
|
|
if closest_mask != last_mask:
|
|
if last_mask and last_mask.has_method("hide_popup"):
|
|
last_mask.hide_popup()
|
|
last_mask = closest_mask
|
|
|
|
if closest_mask:
|
|
if min_dist < INTERACT_DIST:
|
|
if closest_mask.has_method("show_popup"):
|
|
closest_mask.show_popup()
|
|
else:
|
|
if closest_mask.has_method("hide_popup"):
|
|
closest_mask.hide_popup()
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
EventBus.health_changed.emit(health)
|
|
var input_vector = Vector2.ZERO
|
|
input_vector.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
|
|
input_vector.y = Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
|
|
if dash:
|
|
#var dir = global_position.direction_to(get_global_mouse_position())
|
|
velocity += input_vector * move_speed * 40
|
|
dash = false
|
|
var tween = create_tween()
|
|
tween.set_ease(Tween.EASE_IN_OUT)
|
|
tween.tween_property($AnimatedSprite2D, "scale:x", 0.5, 0.1)
|
|
tween.tween_property($AnimatedSprite2D, "scale:x", 1, 0.1)
|
|
input_vector = input_vector.normalized()
|
|
if input_vector != Vector2.ZERO:
|
|
velocity += input_vector * move_speed
|
|
|
|
velocity *= 0.7
|
|
|
|
move_and_slide()
|
|
|
|
func hit():
|
|
health -= 1
|
|
EventBus.health_changed.emit(health)
|
|
if health == 0:
|
|
die()
|
|
EventBus.player_dmg.emit()
|
|
|
|
func die():
|
|
EventBus.screenshake.emit(5)
|
|
var explo = death_explosion.instantiate()
|
|
get_parent().add_child(explo)
|
|
explo.global_position = global_position
|
|
explo.emitting = true
|
|
visible = false
|
|
get_tree().create_timer(2).timeout.connect(SceneTransition.change_scene.bind("res://start_menu.tscn"), true)
|
|
process_mode = Node.PROCESS_MODE_DISABLED
|
|
|
|
func _process(delta: float) -> void:
|
|
charge += delta
|
|
dash_cd += delta
|
|
var enemies = len(get_tree().get_nodes_in_group("enemy"))
|
|
if enemies > 0:
|
|
mask_time_remaining -= delta
|
|
if mask_time_remaining < 0:
|
|
mask_time_remaining = 10
|
|
die()
|
|
EventBus.mask_time_changed.emit(mask_time_remaining / mask_start_time)
|
|
_check_items()
|
|
update_arrow_direction()
|
|
|
|
func update_arrow_direction() -> void:
|
|
var enemies = get_tree().get_nodes_in_group("enemy")
|
|
var closest_enemy: Node2D = null
|
|
var shortest_dist: float = INF # Start with infinity
|
|
var arrow = $Arrow
|
|
|
|
# 1. Find the closest enemy
|
|
for enemy in enemies:
|
|
if enemy is Node2D:
|
|
var dist = global_position.distance_to(enemy.global_position)
|
|
if dist < shortest_dist:
|
|
shortest_dist = dist
|
|
closest_enemy = enemy
|
|
|
|
# 2. Logic: Only show/rotate if they are far away
|
|
if closest_enemy and shortest_dist > 250:
|
|
arrow.visible = true
|
|
arrow.look_at(closest_enemy.global_position)
|
|
else:
|
|
# Hide the arrow if no enemy exists or they are within 350px
|
|
arrow.visible = false
|
|
|
|
func collect_mask(mask : MaskDrop):
|
|
if mask:
|
|
mask.collect(global_position)
|
|
EventBus.mask_changed.emit(mask.mask_type)
|
|
$AnimatedSprite2D.switch_mask(mask.mask_type)
|
|
current_mask = mask.mask_type
|
|
mask_time_remaining = mask_start_time
|
|
|
|
func launch_atk():
|
|
var atk = null
|
|
if (current_mask == Types.mask_types.Melee):
|
|
atk = scithe_attack.instantiate()
|
|
add_child(atk)
|
|
atk.look_at(get_global_mouse_position())
|
|
SoundManager.play_sfx("swing")
|
|
elif (current_mask == Types.mask_types.Ranged):
|
|
atk = heart_attack.instantiate()
|
|
atk.global_position = global_position
|
|
atk.look_at(get_global_mouse_position())
|
|
SoundManager.play_sfx("heart")
|
|
get_parent().add_child(atk)
|
|
elif (current_mask == Types.mask_types.Spit):
|
|
atk = spit_attack.instantiate()
|
|
atk.global_position = global_position
|
|
atk.start_position = global_position
|
|
get_parent().add_child(atk)
|
|
atk.target_position = get_global_mouse_position()
|
|
|
|
atk.set_from_player(true)
|
|
atk.global_position = atk.global_position.move_toward(get_global_mouse_position(), 10 )
|
|
|
|
EventBus.mask_time_changed.emit(mask_time_remaining)
|
|
|
|
|
|
func _input(event: InputEvent) -> void:
|
|
if (event.is_action_pressed("dash")):
|
|
if (dash_cd > dash_base_cd):
|
|
dash = true
|
|
dash_cd = 0
|
|
if (event.is_action_pressed("attack")):
|
|
if (charge > charge_time):
|
|
charge = 0
|
|
launch_atk()
|
|
if (event.is_action_pressed("interact")):
|
|
if closest_mask:
|
|
collect_mask(closest_mask)
|