Godot Version
4.3
Question
So, I am trying to make a grid based movement system. Currently I have 4 way movement that is controlled by InputEvent queuing the direction which is then run through the physics function which wil call my move function. This is regulated by a basic player state enum system. {MOVE, IDLE}
My move function will then calculate direction based on the input event, and then will tween the players position to +32 pixels in said direction. I have already tried the solution in another locked post “Grid movement jittering when used with tweens and camera following player”, since my camera also is attached to the player, however, making the tween process in physics did not solve the issue.
The issue is I have test box sprites that are Area2D, they jitter 1 pixel horizontally or vertically in relation to the direction I am moving. I have tried also to move my character in the physics_process directly using lerp, however, the jitter still persists.
This is frustrating, since my game design requires a grid based movement system, and I have tried various methods to move my characters in these 32 pixel increments, so far all have been jittery. If the camera isn’t attached to the player it isn’t jittery.
func _unhandled_key_input(event: InputEvent) -> void:
var move_names : Array[String] = ["north","south","west","east"]
# Key map strings
for action_name in move_names:
# Iterates through input options to populate move_queue
if event.is_action_pressed(action_name):
# Checks if input is a movement input
if not move_queue.has(move_names.find(action_name)):
# Checks if this is a duplicate
move_queue.push_front(move_names.find(action_name))
# Moves input to front of queue
break
elif event.is_action_released(action_name):
# Checks if event is input release
move_queue.erase(move_names.find(action_name))
# Removes movement from queue
break
# Runs a loop through input_queue;
#checks if input direction is moveable, and if so moves
func _physics_process(_delta: float) -> void:
# Controls smooth movement calls
for action_dir in move_queue:
# Iterates through the move queue
if not state == State.MOVE:
# Prevents rapid execution of movement
if not move_dir[action_dir]:
# Checks if direction is moveable;
# if not sets IDLE and continues
state = State.IDLE
_motion(action_dir)
continue
state = State.MOVE
# Sets state to MOVE to prevent further movement calls
_motion(action_dir)
move._move(self,action_dir)
# Calls _move function in player movement noded
#MOVEMENT CODE CALLED
enum {NORTH,SOUTH,WEST,EAST} # Matches player direction enums
var move_dist : int = 32
# Clarity for what the number is used for
func _move(player:Node2D,dir:int) -> void:
# Controls players movement
var start = player.position
var destination : Vector2
if dir < 2:
# Sets direction to == direction of player input
if dir == 0:
#Value == NORTH
destination = start + Vector2.UP * move_dist
else:
#Value = 1 == SOUTH
destination = start + Vector2.DOWN * move_dist
elif dir == 2:
#Value == WEST
destination = start + Vector2.LEFT * move_dist
else:
#Value = 3 == EAST
destination = start + Vector2.RIGHT * move_dist
var tween = get_tree().create_tween()
# Creates new tween to be used for player movement
tween.set_process_mode(Tween.TWEEN_PROCESS_PHYSICS)
tween.tween_property(player,"position",destination,player.speed)
tween.tween_callback(func(): player.state = 0)
tween.tween_callback(func(): player._motion(dir))