DaveTheCoder
From the print statements:
When it started bouncing: (394.4125, -295.7835)
Before it reached zero: (-0.000315, 3.000107)
get_direction() is called in the Physics Process function, so I can't put a red dot next to it. I'm not sure how to determine what value velocity is (besides zero) when get_direction is called, because it's called every frame if I understand correctly.
This is currently the script:
extends CharacterBody2D
# state
enum States {IDLE, MOVE, BLAST, BOUNCE, SPIN}
var state = States.IDLE # default state
# exportable variables (can be changed in editor)
@export var acceleration = 1.5 # increase in speed by this much
@export var deceleration = 0 # default
@export var deceleration_move = 15 # deceleration when moving with input
@export var deceleration_blast = 210 # deceleration when blasting
@export var dir_last = Vector2(0, 1) # note: needs to be global to work
@export var speed = 0 # default
@export var speed_blast = 500 # speed when blast is performed
@export var speed_move = 100 # speed when moving with input
# functions
func _physics_process(delta): # the delta variable has the value of the frame time that the engine passes to the function.
# local variables
var collision = move_and_collide(velocity * delta)
var dir_input = Input.get_vector("left", "right", "up", "down")
var facing = dir_last # see get_directon() function to see what dir_last equals
match state:
States.IDLE:
if Input.is_action_pressed("move"):
state = States.MOVE # change state
elif Input.is_action_just_released("blast"):
state = States.BLAST # change state
elif Input.is_action_pressed("spin"):
state = States.SPIN
else:
velocity = Vector2.ZERO # idle
speed = 0
States.MOVE:
if ! Input.is_action_pressed("move") and velocity.is_zero_approx():
state = States.IDLE # change state
elif Input.is_action_just_released("blast"):
state = States.BLAST # change state
else:
velocity = dir_input * speed
speed = speed_move
move_and_slide()
States.BLAST:
if Input.is_action_pressed("move"): # if input JUST pressed, not ALREADY pressed
state = States.MOVE
elif collision:
state = States.BOUNCE # change state
else:
velocity = facing * speed # blast in direction facing
velocity = velocity.normalized() * speed # avoid going faster when diagonal
deceleration = deceleration_blast
speed = speed_blast
apply_deceleration(delta)
States.BOUNCE:
if ! collision:
if velocity.is_zero_approx():
state = States.IDLE # change state
elif Input.is_action_pressed("move"):
state = States.MOVE # change state
elif Input.is_action_just_released("blast"):
state = States.BLAST # change state
elif ! Input.is_action_pressed("move"):
apply_deceleration(delta)
deceleration = deceleration_blast
else:
velocity = velocity.bounce(collision.get_normal()) # bounce (get the vector's normal)
# note: only faces diagonal after bouncing, even if moving cardinal
# Experimental state only when 'A' is pressed on keyboard:
States.SPIN:
if Input.is_action_pressed("spin"):
state = States.IDLE
elif Input.is_action_just_released("blast"):
state = States.BLAST # change state
elif Input.is_action_just_released("move"):
deceleration = deceleration_move
apply_deceleration(delta)
elif collision: # says null instance without "collision"
velocity = velocity.bounce(collision.get_normal())
else:
apply_acceleration(dir_input)
move_and_slide()
get_direction()
print("State: ", state)
print("Facing: ", facing)
print("Speed: ", speed)
print("Velocity: ", velocity)
func apply_acceleration(dir_input):
velocity = velocity.move_toward(dir_input * speed_move, acceleration)
func apply_deceleration(delta):
velocity = velocity.move_toward(Vector2.ZERO, deceleration * delta)
func get_direction():
if is_zero_approx(velocity.y):
if velocity.x < 0:
dir_last = Vector2.LEFT
return
elif velocity.x > 0:
dir_last = Vector2.RIGHT
return
if is_zero_approx(velocity.x):
if velocity.y < 0:
dir_last = Vector2.UP
return
elif velocity.y > 0:
dir_last = Vector2.DOWN
return
# diagonal
if velocity.x < 0 and velocity.y < 0:
dir_last = Vector2.LEFT + Vector2.UP #NW when bouncing up?
return
elif velocity.x > 0 and velocity.y < 0:
dir_last = Vector2.RIGHT + Vector2.UP #NE when bouncing up?
return
elif velocity.x < 0 and velocity.y > 0:
dir_last = Vector2.LEFT + Vector2.DOWN #SW # when bouncing down?
return
elif velocity.x > 0 and velocity.y > 0:
dir_last = Vector2.RIGHT + Vector2.DOWN #SE # when bouncing down?
return