Move a sprite with motion.normalized() and inertia

Godot Version

4.3

Question

I’m currently writing a player control with WASD keys.
I’m putting some inertia to the movement anf it works quite well when you release the key or change direction.

What I’m missing is the motion.normalized() to be sure that the motion vector will always have a distance of speed at its maximum. I tried to make some tests like motion = motion.normalized() without success.
Any hint ?

extends CharacterBody2D

var speed: float = 500
const acceleration = 50
var motion = Vector2()

func _physics_process(delta):
	velocity = Input.get_vector("left","right","up","down") * speed
	if velocity.x > 0:
		motion.x = min(motion.x + acceleration, speed)
	elif velocity.x < 0:
		motion.x = max(motion.x - acceleration, -speed)
	else:
		motion.x = lerp(motion.x, 0.0, 0.2)
		
	if velocity.y > 0:
		motion.y = min(motion.y + acceleration, speed)
	elif velocity.y < 0:
		motion.y = max(motion.y - acceleration, -speed)
	else:
		motion.y = lerp(motion.y, 0.0, 0.2)
		
	move_and_collide(motion * delta)

lerp will make your movement frame-dependent, I would avoid it for important gameplay features. Your acceleration is not multiplied by delta so it is applied per-frame.

Maybe you could use move_toward to produce a normalized acceleration. Right now you are performing the acceleration by each axis one at a time, while move_toward can operate on both axis.

var speed: float = 500 # pixels per second
const acceleration: float = 3000 # accelerate by pixels per second
var motion := Vector2()

func _physics_process(delta):
	velocity = Input.get_vector("left","right","up","down") * speed
	motion = motion.move_toward(velocity, acceleration * delta)

	move_and_collide(motion * delta)
1 Like

Wonderful. There is a lot to learn in Godot… ways of doing, existing functions…
This is crazs how clean this line of code is and works flawlessly !

THANKS !