123 lines
3.2 KiB
GDScript
123 lines
3.2 KiB
GDScript
extends CharacterBody2D
|
|
|
|
@onready var camera : Camera2D = get_node("Camera2D")
|
|
@onready var sprite : Sprite2D = get_node("Sprite2D")
|
|
|
|
@onready var health_bar : ProgressBar = get_node("CanvasLayer/ProgressBar")
|
|
@onready var weapon_label : Label = get_node("CanvasLayer/Label")
|
|
|
|
@onready var cooldown_timer : Timer = get_node("cooldown_timer") # after taking damage, don't take damage until the timer is worn off.
|
|
|
|
# Get the gravity from the project settings to be synced with RigidBody nodes.
|
|
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
|
|
# Tracker variable for equipped weapon
|
|
var weapon : Node2D = null
|
|
# Player HP
|
|
var health : int = 100
|
|
# Decides whether player can take damage.
|
|
var cooling_down : bool = false
|
|
|
|
const MAX_HEALTH : int = 100
|
|
|
|
const SPEED : float = 512.0
|
|
const JUMP_VELOCITY : float = -600.0
|
|
const CAMERA_TURN_DIVISOR : float = 8196
|
|
const WEAPON_SPAWN_X_OFFSET : int = 16
|
|
|
|
signal attack()
|
|
|
|
func damage(dmg : int = 10) -> void:
|
|
if cooling_down:
|
|
return
|
|
|
|
health -= dmg
|
|
|
|
cooldown_timer.start()
|
|
cooling_down = true
|
|
return
|
|
|
|
func dequip_weapon() -> void:
|
|
if weapon == null:
|
|
return
|
|
weapon.queue_free()
|
|
weapon = null
|
|
return
|
|
|
|
func equip_weapon(wp : Globals.Weapons) -> void:
|
|
if ! weapon == null or Globals.weapon_unlocked[wp] == false:
|
|
return
|
|
|
|
## This is safe ONLY IF all enum paths are met in Globals.weapon_paths!
|
|
var weapon_scene : Resource = load(Globals.weapon_paths[wp])
|
|
|
|
var weapon_instance : Node2D = weapon_scene.instantiate()
|
|
weapon_instance.set_position(Vector2(WEAPON_SPAWN_X_OFFSET, 0))
|
|
weapon_instance.connect_up(self)
|
|
add_child(weapon_instance)
|
|
|
|
weapon = weapon_instance
|
|
|
|
# Set weapon equip text
|
|
weapon_label.set_text(weapon.get_fancy_name() + " equipped.")
|
|
|
|
return
|
|
|
|
func _ready() -> void:
|
|
camera.make_current()
|
|
equip_weapon(Globals.Weapons.STAFF)
|
|
#equip_weapon(Globals.Weapons.TRACKERSTAFF)
|
|
|
|
func _input(ev : InputEvent) -> void:
|
|
if ev.is_action_released("attack"):
|
|
emit_signal("attack")
|
|
pass
|
|
if ev.is_action_released("dequip_weapon"):
|
|
dequip_weapon()
|
|
return
|
|
|
|
func _process(_delta : float) -> void:
|
|
if health <= 0:
|
|
print("died") # TODO: restart from new
|
|
queue_free()
|
|
|
|
camera.set_rotation(-velocity.x / CAMERA_TURN_DIVISOR)
|
|
|
|
# Fix camera jitter <https://www.reddit.com/r/godot/comments/rk6hlz/how_did_you_solve_2d_camera_smoothing/>
|
|
if velocity == Vector2.ZERO:
|
|
position = position.round()
|
|
|
|
health_bar.set_value(health)
|
|
|
|
return
|
|
|
|
func _physics_process(delta : float) -> void:
|
|
# Add the gravity.
|
|
if not is_on_floor():
|
|
velocity.y += gravity * delta
|
|
|
|
# Handle jump.
|
|
if Input.is_action_just_pressed("jump") and is_on_floor():
|
|
velocity.y = JUMP_VELOCITY
|
|
|
|
# Get the input direction and handle the movement/deceleration.
|
|
# As good practice, you should replace UI actions with custom gameplay actions.
|
|
var direction : float = Input.get_axis("move_left", "move_right")
|
|
if direction:
|
|
velocity.x = direction * SPEED
|
|
|
|
# Dirty character turn around code
|
|
sprite.set_scale(Vector2(direction, 1))
|
|
if ! weapon == null:
|
|
weapon.set_scale(Vector2(direction, 1))
|
|
var tmp_pos : Vector2 = weapon.get_position()
|
|
tmp_pos.x = direction * 16
|
|
weapon.set_position(tmp_pos)
|
|
else:
|
|
velocity.x = move_toward(velocity.x, 0, SPEED)
|
|
|
|
move_and_slide()
|
|
|
|
|
|
func _on_cooldown_timer_timeout():
|
|
cooling_down = false
|