ComBot-X3000/src/scripts/actors/player.gd

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