212 lines
4.8 KiB
GDScript
212 lines
4.8 KiB
GDScript
class_name Player
|
|
extends CharacterBody2D
|
|
|
|
signal unequip()
|
|
signal coin_update(int)
|
|
|
|
signal health_update(int)
|
|
signal death()
|
|
|
|
|
|
const BASE_MOVEMENT_SPEED := 10000
|
|
const BASE_JUMP_HEIGHT := -250
|
|
|
|
|
|
|
|
@export
|
|
var jump_platform: PackedScene
|
|
|
|
@export
|
|
var animation_player: AnimationPlayer
|
|
|
|
@export
|
|
var arms_sprite: Sprite2D
|
|
|
|
@export
|
|
var damage_sound: AudioStream
|
|
|
|
@export
|
|
var sword_sound: AudioStream
|
|
|
|
@export_category("Combat")
|
|
@export
|
|
var max_hp: int = 25
|
|
|
|
|
|
@export_dir
|
|
var equipment_dir: String
|
|
|
|
@export
|
|
var equipment_node: Node2D
|
|
|
|
@export_category("Movement")
|
|
@export
|
|
var default_speed: float = 1
|
|
|
|
@export
|
|
var default_jump_height: float = 1
|
|
|
|
|
|
@onready
|
|
var health: int = max_hp :
|
|
set(value):
|
|
value = clampi(value, 0, max_hp)
|
|
|
|
if value != health:
|
|
health_update.emit(value)
|
|
if value == 0:
|
|
death.emit()
|
|
health = value
|
|
get:
|
|
return health
|
|
|
|
@onready
|
|
var default_gravity: float = ProjectSettings.get_setting("physics/2d/default_gravity")
|
|
|
|
var coins: int = 0 :
|
|
set(value):
|
|
if value != coins:
|
|
coin_update.emit(coins)
|
|
coins = value
|
|
get:
|
|
return coins
|
|
|
|
var motion: Vector2 = Vector2.ZERO
|
|
|
|
var currently_equiped: String = "pistol"
|
|
|
|
var extra_jumps: int = 2
|
|
|
|
var current_jumps: int = 0
|
|
|
|
var jump_height: float = 0
|
|
|
|
func _ready() -> void:
|
|
self.add_item("pistol")
|
|
self.add_item("saber")
|
|
|
|
func deal_damage(dmg = 1) -> void:
|
|
self._play_audio(damage_sound)
|
|
self.health -= dmg
|
|
|
|
func switch_sheath() -> void:
|
|
var item := get_currently_equiped_node()
|
|
item.toggle_sheath()
|
|
|
|
|
|
func _play_audio(track: AudioStream) -> void:
|
|
var audio_player = get_node_or_null("AudioStreamPlayer")
|
|
if !audio_player:
|
|
audio_player = AudioStreamPlayer.new()
|
|
audio_player.name = "AudioStreamPlayer"
|
|
self.add_child(audio_player)
|
|
audio_player.stream = track
|
|
audio_player.volume_db = -30
|
|
audio_player.play()
|
|
|
|
func pickup_coin(coin_value: int = 1) -> void:
|
|
self.coins += coin_value
|
|
|
|
func _process(_delta: float) -> void:
|
|
var item = get_currently_equiped_node()
|
|
arms_sprite.visible = (item == null || item.is_sheathed())
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
|
|
self._combat_process(delta)
|
|
self._gravity_process(delta)
|
|
self._movement_process(delta)
|
|
self._animation_process(delta)
|
|
|
|
self.set_velocity(self.motion)
|
|
self.set_up_direction(Vector2.UP)
|
|
self.move_and_slide()
|
|
self.motion = self.velocity
|
|
|
|
func _combat_process(_delta: float) -> void:
|
|
|
|
for i in range(0, 2):
|
|
if Input.is_action_just_pressed("equip_slot_%s" % [str(i+1)]):
|
|
if self.equipment_node.get_child_count() > i:
|
|
self.equip(self.equipment_node.get_child(i).name)
|
|
|
|
if Input.is_action_just_pressed("sheath"):
|
|
self.switch_sheath()
|
|
if Input.is_action_pressed("attack") and self.get_currently_equiped_node().is_sheathed():
|
|
self.switch_sheath()
|
|
|
|
func _gravity_process(delta: float) -> void:
|
|
self.motion.y += self.default_gravity * delta
|
|
if self.is_on_floor():
|
|
self.motion.y = 0
|
|
|
|
func _movement_process(delta: float) -> void:
|
|
|
|
# Horizontal movement
|
|
if Input.is_action_pressed("move_right"):
|
|
self.motion.x = (self.BASE_MOVEMENT_SPEED * delta) * self.default_speed
|
|
elif Input.is_action_pressed("move_left"):
|
|
self.motion.x = (-self.BASE_MOVEMENT_SPEED * delta) * self.default_speed
|
|
else:
|
|
self.motion.x = 0
|
|
|
|
# Handle jumps
|
|
if Input.is_action_just_pressed("jump"):
|
|
if self.is_on_floor():
|
|
|
|
if Input.is_action_pressed("move_down"):
|
|
self.position.y += 1
|
|
else:
|
|
self.jump()
|
|
self.current_jumps = self.extra_jumps
|
|
|
|
elif self.current_jumps > 0:
|
|
self.jump()
|
|
self.spawn_jump_platform()
|
|
self.current_jumps -= 1
|
|
|
|
func jump() -> void:
|
|
self.motion.y = self.BASE_JUMP_HEIGHT * self.default_jump_height
|
|
|
|
func spawn_jump_platform() -> void:
|
|
self._play_audio(sword_sound)
|
|
var platform = self.jump_platform.instantiate()
|
|
self.get_parent().add_child(platform)
|
|
platform.position = Vector2(self.position.x, self.position.y + 4)
|
|
|
|
func _animation_process(_delta: float) -> void:
|
|
|
|
if animation_player is PlayerAnimationPlayer:
|
|
if get_global_mouse_position().x < global_position.x:
|
|
self.animation_player.set_direction(Vector2.LEFT)
|
|
else:
|
|
self.animation_player.set_direction(Vector2.RIGHT)
|
|
|
|
if not self.is_on_floor():
|
|
self.animation_player.safe_play("jump")
|
|
elif abs(self.motion.x) > 0:
|
|
self.animation_player.safe_play("walk")
|
|
else:
|
|
self.animation_player.safe_play("idle")
|
|
|
|
func get_currently_equiped_node() -> Equipment:
|
|
return self.equipment_node.get_node_or_null(self.currently_equiped)
|
|
|
|
func equip(equipment_id: String) -> void:
|
|
if equipment_id == self.currently_equiped:
|
|
self.switch_sheath()
|
|
else:
|
|
var current = self.get_currently_equiped_node()
|
|
if not current.is_sheathed():
|
|
current.toggle_sheath()
|
|
|
|
currently_equiped = equipment_id
|
|
current = self.get_currently_equiped_node()
|
|
if current.is_sheathed():
|
|
current.toggle_sheath()
|
|
|
|
func add_item(equiment_id: String) -> void:
|
|
var item = load("%s/%s.tscn" % [equipment_dir, equiment_id]).instantiate()
|
|
item.name = equiment_id
|
|
equipment_node.add_child(item)
|