Let's imagine I have some character that can rotate in 360 degrees, and I am tracking its position as x and y.
I am using sin
and cos
to determine its movement:
x += speed * cos(rotation)
y += speed * sin(rotation)
This works fine, but I figure I want an acceleration based system instead. So rather than increasing speed, I increase acceleration which then increases speed:
x_velocity += speed * cos(rotation)
y_velocity += speed * sin(rotation)
x += x_velocity
y += y_velocity
However, I don't want this character to be able to accelerate indefinitely and therefore I want to limit its top speed. Now, I could do this:
if x_velocity > maxspeed then x_velocity = maxspeed
if y_velocity > maxspeed then y_velocity = maxspeed
but this is imperfect, as it means you can travel 44% faster if you move at a perfect diagonal than if you travel in a cardinal direction.
So I use the pythagorean theorem, but I immediately run into a problem.
if sqrt(x_velocity^2 + y_velocity^2) > maxspeed then ???
Is there a solution? I cannot simply define it equal to maxspeed
like before, but I also cannot completely allocate all the velocity to one axis, since that would change the direction. How do I determine the velocity to limit it at?
Just use overall velocity
velocity = Min(max_velocity, velocity + speed) //really acceleration instead of speed
x_velocity = velocity * cos(rotation)
y_velocity = velocity * sin(rotation)
x += x_velocity
y += y_velocity
If you have to maintain x_velocity and y_velocity (by some strange reason), then you can limit overall velocity through it's components with direction preserving:
... update x_velocity, y_velocity
vel = sqrt(x_velocity^2 + y_velocity^2)
if vel > max_velocity then
x_velocity = x_velocity * max_velocity / vel
y_velocity = y_velocity * max_velocity / vel