pixel.rip

Sin and Cos for Movement

2024-11-20 in codex

Goal

Move an object at a given speed and angle using sin() and cos() for the x and y values.

Solution

Playable Example

Playable Example - GitHub

How it Works

It is fairly straightforward to get and object to move along an X and Y axis. Let’s say you have an object player with x and y coordinates. Some simple math like this would move that player:


player.x += 1 --increase x position; moves left
player.x -= 1 --decrease x position; moves right
player.y += 1 --increase y position; moves down
player.y -= 1 --decrease y position; moves up

But what happens when an object needs to move on the diagonal? It turns out PICO-8’s sin() and cos() functions are suited to this.

Unsurprisingly, a deep understanding of the trigonomety behind these functions eludes me–but I’ll leave that to the mathematicians. What I do know is that we can use these functions move an object in any direction with an angle and a speed.


angle = 0.125 
speed = 2.5

The angle that our sin() and cos() functions need is a decimal value between 0 and 1. If you picture a complete circle then we start at the bottom with 0 (0° or “down”) move clockwise:

Angles around a circle

  • 0.25 is 90° (left)
  • 0.375 is 135° (up and left)
  • 0.5 is 180° (up)
  • 0.625 is 225° (up and right)
  • and so on until…
  • 1 is 360° (down, again)

The speed is the distance on the screen (pixels) that the object will move per frame.

So, to make something move on a diagonal, we pass the angle into the sin() function for x (and the cos() function for the y) then multiply the speed.


angle = 0.125
speed = 2.5

obj.x += sin(angle) * speed
obj.y += cos(angle) * speed

Thanks

Episode 24 of the Lazy Devs’ “Making a Shmup” Tutorial has a fantastic breakdown of the usefulness of sin() and cos() for moving on angles.