Godot Version
Godot 4.3
Question
Hello! This is a top-down pixel art game where the player can move in 8 directions. I am moving a CharacterBody2D with the move_and_slide() function. Here is my player movement code:
extends CharacterBody2D
const SPEED := 60.0
const ACCELERATION := 800.0
func _physics_process(delta: float) -> void:
# Gets direction input and normalises it
var direction : Vector2
direction.x = Input.get_axis("ui_left", "ui_right")
direction.y = -Input.get_axis("ui_down", "ui_up") # Flip y-axis
direction = direction.normalized()
# Moves with acceleration
velocity = velocity.move_toward(direction * SPEED, ACCELERATION * delta)
move_and_slide()
When moving at 60 speed in any direction (without normalisation of the direction), there is no jitter. This is because the player is moving 60 pixels per second, which matches the physics ticks per second and my refresh rate. However when the direction is normalised, the player does not move at 60 pixels per second when moving diagonally. This should be fine, however there is a strange staircase effect that happens.
What happens (at 60 speed, normalised):
Here it is slower so it’s easier to see (at 4 speed, normalised):
This is what’s happening:
If I do NOT normalise the direction (so it remains at 60), then it moves as intended:
The stretch mode of the game is set to viewport, and “Snap 2D Transforms to Pixels” is enabled. Setting the stretch mode to canvas_items and disabling “Snap 2D Transforms to Pixels” obviously fixes the issue, however then it would not be a true pixel art game.
Putting global_position = round(global_position)
after the move_and_slide()
also fixes the problem, however then the acceleration of the movement is nullified because it rounds the velocity to 0 when trying to move less then 0.5 pixels. This is clear when decreasing the acceleration constant so that the acceleration is amplified with the move_toward() function.
I initially thought that the move_and_slide function was the problem, however the issue still occurs when moving the player by adjusting it’s position directly, like with position += direction
.
The issue would be fixed if there’s a way to move the player both up/down and across on the same frame instead of different frames, but I’m not sure how I would go about implementing that. Again, the issue occurs when the direction is normalised (or not at speed of 60 pixels per second). Help would be greatly appreciated!