(ABSOLUTE NOOB) how to check last input?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By ylapointe

so ive been trying to figure this out on my own through trial and error and its driving me nuts… there’s got to be a better way right?

basically i’m creating a grid based movement system. but i want it to only take in the last direction i press while ignoring any other direction…

for example:
when i press right i want it to move right, but if i press down while still holding right i want it to take in the last pressed key (down) while ignoring the previous key (right).

here’s what my noob brain could sort of piece together.

extends KinematicBody2D

#----constants-------
const TILESIZE = 32

#----variables---------
var walk_speed = 4
var moving = false
var current_position = Vector2(0,0)
var last_direction = Vector2(0,0)
var current_direction = Vector2(0,0)
var percent_to_next_position = 0.0

#----debug variables------
export var debug = true

#----debug stuff-------
func debugInfo():
	print(" last direction: ", last_direction, " // current direction: ", current_direction, " // current position: ", current_position, " // percent to next tile: ", percent_to_next_position, " // moving: ", moving)
	return

func get_current_variable_values():
	if debug == true:
		print(debugInfo())
	return

#----main code---------
func _ready():
	get_current_tile()

func _physics_process(delta):
	if moving == false:
		get_new_direction()
	else:
		move_to_next_tile(delta)
		
	return

func get_current_tile():
	current_position = position
	return

func get_new_direction():
	get_current_variable_values()
	get_player_input()
	if current_direction != Vector2.ZERO:
		get_current_tile()
		moving = true
	return

func get_player_input():
	current_direction.x = int(Input.is_action_pressed("RIGHT")) - int(Input.is_action_pressed("LEFT"))
	current_direction.y = int(Input.is_action_pressed("DOWN")) - int(Input.is_action_pressed("UP")) 
	calculate_direction()
	return

func calculate_direction():
	if (current_direction.y && current_direction.x !=0) && (current_direction != last_direction): 
		current_direction -= last_direction
	elif current_direction == last_direction:
		current_direction = last_direction
	elif current_direction == Vector2.ZERO:
		current_direction *= Vector2.ZERO
	last_direction = current_direction
	return

func reset_next_tile():
	position = current_position + (TILESIZE * current_direction)
	percent_to_next_position = 0.0
	moving = false
	return
	
func move_to_next_tile(delta):
	percent_to_next_position += walk_speed * delta
	if percent_to_next_position >= 1.0:
		reset_next_tile()
	else:
		position = current_position + (TILESIZE * current_direction * percent_to_next_position)
	return

i got something that kinda works but i know its not ideal. what am i doing wrong?

edit: i know i have a ton of separate functions that could be condensed into 1 function but this was the only way for me to wrap my head around what the code was doing. sorry in advance for my noob brain.

i know i have a ton of separate functions that could be condensed into 1 function

It’s a good idea to break up the code when it grows too large. :wink:

Maybe the get_player_input() function could check for the value of certain vector components? For instance:

if current_direction.x > 0.01:
    # Do some movement on the x-axis.
elif current_direction.y > 0.01:
    # Do some movement on the y-axis.

Please note that this method hasn’t been tested. As a side note, it is unnecessary for each function to have a return statement. Only put that in when the caller requires some data from the function.

Ertain | 2021-09-08 17:56

thanks for clearify about the return statement! i wasn’t actually sure how it worked and read some where that it’s used to return to the line the function was called.

as for your suggestion:
i’ve thought of that as well, but wouldn’t that prioritize the x axis over the y though? for example if im pressing right then add up (so i’m pressing right & up) it would still only go right. or am i missing something?

i’m trying to create a system that would basically take the latest input axis and ONLY use that axis and disregard the rest.

ylapointe | 2021-09-09 12:50

Yeah, I thought about the axis priorities, too. I had another idea to use an input system similar to those found in beginner tutorials:

velocity = Vector2.ZERO
if Input.is_action_pressed("RIGHT"):
    velocity.x += 1
if Input.is_action_pressed("LEFT"):
    velocity.x -= 1
if Input.is_action_pressed("DOWN"):
    velocity.y += 1
if Input.is_action_pressed("UP"):
    velocity.y -= 1

From what I’ve found, when the user pushes two inputs at once, the first input is taken, and the second input is disregarded. Though I don’t know whether this is suitable for your needs.

Ertain | 2021-09-09 18:04

that code allows for diagonals which is unfortunately not what im looking for.

ylapointe | 2021-09-11 17:14

ok so i think i got it…

here’s the full code for those that also struggled with the same problem.

#-----------------credits-------------------
# based heavily off code from Arkeve
# link: https://www.youtube.com/watch?v=jSv5sGpnFso

extends KinematicBody2D

#----constants-------------------------------------
const TILESIZE = 32

#----variables-------------------------------------
var walk_speed = 4
var moving = false
var last_direction = Vector2.ZERO
var current_direction = Vector2.ZERO
var initial_position = Vector2.ZERO
var percent_to_next_position = 0.0

#----main code--------------------------------------
func _ready():
   initial_position = position

func _physics_process(delta):
	if moving == false:
		#----get current_direction-----
		current_direction.y = int(Input.is_action_pressed("DOWN")) - int(Input.is_action_pressed("UP"))
		current_direction.x = int(Input.is_action_pressed("RIGHT")) - int(Input.is_action_pressed("LEFT")) 
		
		#----add last_direction and current_direction x and y values ----
		if (current_direction.x && current_direction.y != 0) and (last_direction.x || last_direction.y != 0):
			current_direction += last_direction
		#----previous_direction values are zeroed from current_direction 
		if current_direction.x < -1 or current_direction.x > 1:
			current_direction.x = 0
		if current_direction.y < -1 or current_direction.y > 1:
			current_direction.y = 0
		#----after filtering through above conditions the new direction 
		#----will always be a 1/-1 in either x or y but never both at the same time 
		if current_direction != Vector2.ZERO:
			initial_position = position
			moving = true
		
		last_direction = current_direction
	else:
		percent_to_next_position += walk_speed * delta
		if percent_to_next_position >= 1.0:
			position = initial_position + (TILESIZE * current_direction)
			percent_to_next_position = 0.0
			moving = false
		else:
			position = initial_position + (TILESIZE * current_direction * percent_to_next_position)

after figuring it out i condensed it as well…

i also included credit since i forgot to do it originally and figured i should probably do that

ylapointe | 2021-09-11 20:42