How to stop my acceleration from increasing

Godot Version

4.5

I'm trying to cap the speed at 160.

It keeps on going over.

My code

const SPEED = 300.0
const JUMP_VELOCITY = -400.0


m

var acceleration := 40

func _physics_process(delta: float) -> void:

var direction := Input.get_axis("left", "right")
	if direction:
		velocity.x = direction * acceleration
		acceleration += 40

else:
	velocity.x = move_toward(velocity.x, 0, SPEED)
	direction = 0
if acceleration == 160:
	print("Max Speed")
	acceleration == 160
	
if direction == 0:
	acceleration = 0

Set it to 160 whenever it’s greater than that.

const SPEED = 300.0
const JUMP_VELOCITY = -400.0

# You are multiplying this with a float (direction) and had
# declared it implicitly as an int, so I changed it to a float.
var acceleration: float = 40.0


func _physics_process(delta: float) -> void:
	var direction := Input.get_axis("left", "right")
	if direction:
		velocity.x = direction * acceleration
		acceleration += 40.0
		clampf(acceleration, 40.0, 160.0) # the value cannot go below 40.0 or above 160.0
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED)
		acceleration = 40.0

	move_and_slide()

This is very close, you want to assign the max speed if acceleration goes over the max speed

if acceleration > 160:
	print("Max Speed")
	acceleration == 160

clampf returns the clamped value, it does not modify acceleration on it’s own so you’d have to also assign acceleration

acceleration = clampf(acceleration, 40.0, 160.0)
3 Likes

Thanks @gertkeno. Good catch!

const SPEED = 300.0
const JUMP_VELOCITY = -400.0

# You are multiplying this with a float (direction) and had
# declared it implicitly as an int, so I changed it to a float.
var acceleration: float = 40.0


func _physics_process(delta: float) -> void:
	var direction := Input.get_axis("left", "right")
	if direction:
		velocity.x = direction * acceleration
		acceleration += 40.0
		acceleration  = clampf(acceleration, 40.0, 160.0) # the value cannot go below 40.0 or above 160.0
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED)
		acceleration = 40.0

	move_and_slide()

To questions what does clampf do and the acceleration is accelerating to top speed to fast

You can read more about clampf in the documentation, in Godot you can hold ctrl and click on any word in the script to read more about such functions/properties/signals. clampf takes a value and returns the same value if it’s between the minimum and maximum value, it is this function

func clampf(value: float, minimum: float, maximum: float) -> float:
    if value < minimum:
        return minimum
    elif value > maximum:
        return maximum
    else:
        return value

Your acceleration is currently adding 40 per physics step, if you use delta then it will increase by 40 per second which may be closer to what you want

func _physics_process(delta: float) -> void:
	var direction := Input.get_axis("left", "right")

	velocity.x = direction * acceleration
	acceleration += 40 * delta
	if acceleration > 160:
		acceleration = 160

	if direction == 0:
		acceleration = 0
1 Like

In most typical cases you want to integrate velocity over time, not acceleration. Acceleration is often a constant. Your current code integrates acceleration instead, which may result in unwanted behavior. For example, if your acceleration is high and the player suddenly switches direction, the same high acceleration will continue to work but in opposite direction, abruptly changing the velocity.

So (in pseudo code):

acceleration = some_constant
velocity += direction * acceleration * delta_time

And then you clamp the velocity magnitude, because that’s what you typically want to limit.

1 Like

It might be worth it to back up and ask why you are doing it this way, and what you are trying to accomplish.

acceleration

This is the math (calculus) formula for acceleration. Acceleration equals the change in velocity over time, divided by the change in time.

_physics_process() handles dividing by time with the value delta, which by default divides anything you multiply it by, into 60 segments per second (because it, itself is a fraction in decimal form).

velocity.x = direction * acceleration
acceleration += 40.0

In your original code, you are saying for the first 1/60th of a second, the velocity is 40 in the direction you want to move. At 2/60th of a second, the velocity is 80. At 3/60th it is 120, and at 4/60th of a second, and as long as the player keeps moving, their velocity is 160. That change is not something a human can notice with their eyes on the screen.

In your code, technically acceleration is the change over time of velocity plotted on a curve for many physics ticks you want to measure it. Roughly:

160   _________________
120  /
80  /
40 /

If you wanted an acceleration you could visibly see, change it to something like this:

velocity.x = direction * acceleration * delta
acceleration += 1.333
acceleration  = clampf(acceleration, 40.0, 160.0)

Every half second, you will get an increase of 40, and at the end of 2 seconds you’ll be going at 160. You can change the amount from 1.333 to something larger or smaller to change the rate of acceleration. Also, from a purely physics point of view, the acceleration variable should be speed.

So you could rewrite it as:

const MAX_SPEED = 160.0
const START_SPEED = 40.0
const JUMP_VELOCITY = -400.0

var speed: float = START_SPEED

func _physics_process(delta: float) -> void:
	var direction := Input.get_axis("left", "right")
	if direction:
		velocity.x = direction * speed * delta
		speed += 1.333
		speed = clampf(acceleration, 40.0, 160.0)
	else:
		velocity.x = move_toward(velocity.x, 0, MAX_SPEED * delta)
		speed = START_SPEED

	move_and_slide()