Initial commit
This commit is contained in:
203
scenes/characters/Player.gd
Normal file
203
scenes/characters/Player.gd
Normal file
@@ -0,0 +1,203 @@
|
||||
extends CharacterBody2D
|
||||
|
||||
class_name Player
|
||||
|
||||
"""
|
||||
This implements a very rudimentary state machine. There are better implementations
|
||||
in the AssetLib if you want to make something more complex. Also it shares code with Enemy.gd
|
||||
and probably both should extend some parent script
|
||||
"""
|
||||
|
||||
@export var WALK_SPEED: int = 70 # pixels per second
|
||||
@export var ROLL_SPEED: int = 1000 # pixels per second
|
||||
@export var hitpoints: int = 3
|
||||
|
||||
var linear_vel = Vector2()
|
||||
var roll_direction = Vector2.DOWN
|
||||
|
||||
signal health_changed(current_hp)
|
||||
|
||||
var despawn_fx = preload("res://scenes/misc/DespawnFX.tscn")
|
||||
|
||||
var anim = ""
|
||||
var new_anim = ""
|
||||
|
||||
const N = Vector2.UP
|
||||
const NE = Vector2(cos(1*PI/4),sin(1*PI/4))
|
||||
const E = Vector2.RIGHT
|
||||
const SE = Vector2(cos(7*PI/4),sin(7*PI/4))
|
||||
const S = Vector2.DOWN
|
||||
const SW = Vector2(cos(5*PI/4),sin(5*PI/4))
|
||||
const W = Vector2.LEFT
|
||||
const NW = Vector2(cos(3*PI/4),sin(3*PI/4))
|
||||
|
||||
|
||||
|
||||
enum { STATE_BLOCKED, STATE_IDLE, STATE_WALKING, STATE_ATTACK, STATE_ROLL, STATE_DIE, STATE_HURT }
|
||||
|
||||
|
||||
@export var facing = "S" # (String, "up", "down", "left", "right")
|
||||
var state = STATE_IDLE
|
||||
var direction = S
|
||||
|
||||
# Move the player to the corresponding spawnpoint, if any and connect to the dialog system
|
||||
func _ready():
|
||||
var spawnpoints = get_tree().get_nodes_in_group("spawnpoints")
|
||||
for spawnpoint in spawnpoints:
|
||||
if spawnpoint.name == Globals.spawnpoint:
|
||||
global_position = spawnpoint.global_position
|
||||
break
|
||||
if not (
|
||||
Dialogs.dialog_started.connect(_on_dialog_started) == OK and
|
||||
Dialogs.dialog_ended.connect(_on_dialog_ended) == OK ):
|
||||
printerr("Error connecting to dialog system")
|
||||
pass
|
||||
|
||||
|
||||
func _physics_process(_delta):
|
||||
|
||||
## PROCESS STATES
|
||||
match state:
|
||||
STATE_BLOCKED:
|
||||
# new_anim = "idle_" + facing
|
||||
$anims.stop()
|
||||
pass
|
||||
STATE_IDLE:
|
||||
if (
|
||||
Input.is_action_pressed("move_down") or
|
||||
Input.is_action_pressed("move_left") or
|
||||
Input.is_action_pressed("move_right") or
|
||||
Input.is_action_pressed("move_up")
|
||||
):
|
||||
state = STATE_WALKING
|
||||
if Input.is_action_just_pressed("attack"):
|
||||
state = STATE_ATTACK
|
||||
# if Input.is_action_just_pressed("roll"):
|
||||
# state = STATE_ROLL
|
||||
# roll_direction = Vector2(
|
||||
# - int( Input.is_action_pressed("move_left") ) + int( Input.is_action_pressed("move_right") ),
|
||||
# -int( Input.is_action_pressed("move_up") ) + int( Input.is_action_pressed("move_down") )
|
||||
# ).normalized()
|
||||
# _update_facing()
|
||||
|
||||
# new_anim = "idle_" + facing
|
||||
$anims.stop()
|
||||
pass
|
||||
STATE_WALKING:
|
||||
if Input.is_action_just_pressed("attack"):
|
||||
state = STATE_ATTACK
|
||||
if Input.is_action_just_pressed("roll"):
|
||||
state = STATE_ROLL
|
||||
|
||||
linear_vel = velocity
|
||||
|
||||
var target_speed = Vector2(0,0)
|
||||
|
||||
if Input.is_action_pressed("move_down"):
|
||||
target_speed += Vector2.DOWN
|
||||
if Input.is_action_pressed("move_left"):
|
||||
target_speed += Vector2.LEFT
|
||||
if Input.is_action_pressed("move_right"):
|
||||
target_speed += Vector2.RIGHT
|
||||
if Input.is_action_pressed("move_up"):
|
||||
target_speed += Vector2.UP
|
||||
|
||||
|
||||
target_speed = target_speed.normalized() * WALK_SPEED
|
||||
target_speed.y *= 0.50 # compensa visione isometrica
|
||||
#linear_vel = linear_vel.linear_interpolate(target_speed, 0.9)
|
||||
linear_vel = target_speed
|
||||
set_velocity(linear_vel)
|
||||
roll_direction = linear_vel.normalized()
|
||||
move_and_slide()
|
||||
|
||||
_update_facing()
|
||||
|
||||
if linear_vel.length() > 5:
|
||||
new_anim = "walk_" + facing
|
||||
$anims.play()
|
||||
else:
|
||||
goto_idle()
|
||||
pass
|
||||
STATE_ATTACK:
|
||||
new_anim = "walk_" + facing # was splash_
|
||||
pass
|
||||
STATE_ROLL:
|
||||
if roll_direction == Vector2.ZERO:
|
||||
state = STATE_IDLE
|
||||
else:
|
||||
set_velocity(linear_vel)
|
||||
move_and_slide()
|
||||
linear_vel = velocity
|
||||
var target_speed = Vector2()
|
||||
target_speed = roll_direction
|
||||
target_speed *= ROLL_SPEED
|
||||
#linear_vel = linear_vel.linear_interpolate(target_speed, 0.9)
|
||||
linear_vel = target_speed
|
||||
new_anim = "roll"
|
||||
STATE_DIE:
|
||||
new_anim = "die"
|
||||
STATE_HURT:
|
||||
new_anim = "hurt"
|
||||
|
||||
## UPDATE ANIMATION
|
||||
if new_anim != anim:
|
||||
anim = new_anim
|
||||
$anims.play(anim)
|
||||
pass
|
||||
|
||||
|
||||
func _on_dialog_started():
|
||||
state = STATE_BLOCKED
|
||||
|
||||
func _on_dialog_ended():
|
||||
state = STATE_IDLE
|
||||
|
||||
|
||||
## HELPER FUNCS
|
||||
func goto_idle():
|
||||
linear_vel = Vector2.ZERO
|
||||
# new_anim = "idle_" + facing
|
||||
state = STATE_IDLE
|
||||
|
||||
|
||||
func _update_facing():
|
||||
if Input.is_action_pressed("move_left"):
|
||||
facing = "W"
|
||||
if Input.is_action_pressed("move_right"):
|
||||
facing = "E"
|
||||
if Input.is_action_pressed("move_up"):
|
||||
facing = "N"
|
||||
if Input.is_action_pressed("move_left"):
|
||||
facing = "NW"
|
||||
if Input.is_action_pressed("move_right"):
|
||||
facing = "NE"
|
||||
if Input.is_action_pressed("move_down"):
|
||||
facing = "S"
|
||||
if Input.is_action_pressed("move_left"):
|
||||
facing = "SW"
|
||||
if Input.is_action_pressed("move_right"):
|
||||
facing = "SE"
|
||||
|
||||
|
||||
func despawn():
|
||||
var despawn_particles = despawn_fx.instantiate()
|
||||
get_parent().add_child(despawn_particles)
|
||||
despawn_particles.global_position = global_position
|
||||
hide()
|
||||
await get_tree().create_timer(5.0).timeout
|
||||
get_tree().reload_current_scene()
|
||||
pass
|
||||
|
||||
|
||||
func _on_hurtbox_area_entered(area):
|
||||
if state != STATE_DIE and area.is_in_group("enemy_weapons"):
|
||||
hitpoints -= 1
|
||||
emit_signal("health_changed", hitpoints)
|
||||
var pushback_direction = (global_position - area.global_position).normalized()
|
||||
set_velocity(pushback_direction * 5000)
|
||||
move_and_slide()
|
||||
state = STATE_HURT
|
||||
if hitpoints <= 0:
|
||||
state = STATE_DIE
|
||||
pass
|
||||
Reference in New Issue
Block a user