Movement continues for diagonal movement after releasing one key
12. Květen 2024 v 13:05
For example, if I press W key and D key, that would produce a movement in the Northeast position. However, if I release either key (meaning I am holding only W or D at the moment), the movement still continues going northeast when I want it to go east if it is D only, and north if it is W only. However, if I release both of the keys and then press either W or D it works perfectly.
The code for my main CharacterBody2D:
extends CharacterBody2D
class_name Player
var x_input: float = 0.0
var y_input: float = 0.0
var pause_lock: bool = false
@onready var sprite = $PlayerSprite
@onready var f_arm = $PlayerSprite/Torso/R_Arm
@onready var b_arm = $PlayerSprite/Torso/L_Arm
@onready var hand = $PlayerSprite/Torso/R_Arm/Hand
@onready var aim_pivot = $PlayerSprite/Torso/AimPivot
@onready var fsm = $FSM
@onready var leg_anim = $LegsAnimation
@export var MAX_SPEED : int = 50
@export var ACCELERATION : int = 1000
@export var FRICTION : float = 1.0
@export var base_hp : int = 0
@onready var hp: int = base_hp
var motion : Vector2 = Vector2.ZERO
var direction : Vector2 = Vector2.ZERO
func _player_input():
x_input = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
y_input = Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
direction = Vector2(x_input, y_input).normalized()
func _idle():
motion.x = lerp(motion.x, 0.0, FRICTION)
motion.y = lerp(motion.y, 0.0, FRICTION)
func _move(delta, direction):
motion += direction * ACCELERATION * delta
motion.x = clamp(motion.x, -MAX_SPEED, MAX_SPEED)
motion.y = clamp(motion.y, -MAX_SPEED, MAX_SPEED)
print(motion)
velocity = motion
move_and_slide()
func aim(pos: Vector2):
_flip_player_sprite(pos.x < self.global_position.x)
if (pos.x < self.global_position.x):
f_arm.rotation = lerp_angle(f_arm.rotation, -(aim_pivot.global_position - pos).angle(), (0.10))
else:
f_arm.rotation = lerp_angle(f_arm.rotation, (pos - aim_pivot.global_position).angle(), (0.10))
b_arm.look_at(hand.global_position)
func _flip_player_sprite(flip: bool):
match flip:
true:
sprite.scale.x = -1
false:
sprite.scale.x = 1
func _animate_legs():
if (direction == Vector2.ZERO):
leg_anim.play("Idle")
else:
var is_forward: bool = (
(sprite.scale.x == 1)
or (sprite.scale == Vector2(-1,1) and x_input < 0)
)
match is_forward:
true:
leg_anim.play("Walk_Forward")
false:
leg_anim.play("Walk_Backward")
The code for the finite state machine attached as a child:
extends Node
enum STATES {IDLE, MOVE}
var state: int = 0
@onready var parent = get_parent()
func _physics_process(delta):
run_state(delta)
func run_state(delta):
parent._player_input()
parent.aim(parent.get_global_mouse_position())
match state:
STATES.IDLE:
parent._idle()
if (parent.direction != Vector2.ZERO):
_set_state(STATES.MOVE)
STATES.MOVE:
parent._animate_legs()
parent._move(delta, parent.direction)
if (parent.direction == Vector2.ZERO):
_set_state(STATES.IDLE)
func _set_state(new_state: int):
if (state == new_state):
return
state = new_state