Rotating Planets Tutorial

Demoscene Tutorials / Julio Choy

When you finish building this demo project, you'll end up with something that looks like this:

This project is compatible with Pixel Vision 8 v0.9.0.


Step 1

Create a new Lua file called code.lua in your project folder.

Step 2

Add the following local variables:

001 local planets = {} 002 local moons = {} 

We'll be generating several planets and moons to draw and animate later, so we're making two tables to keep track of them.

Step 3

Create a new local variable called moonOrbitRadius inside the script:

003 local moonOrbitRadius = 16 

This variable will make a moon orbit 16 pixels away from its planet.

Step 4

Create a new local variable called angleSpeed inside the script:

004 local angleSpeed = 1 

The angle speed determines how fast a moon will rotate around its planet, and 1 degree/frame is a decent speed.

Step 5

Create a new function called Init():

005 function Init() 
006  
007 end

Step 6

Create the following Loop:

006 for i = 1, 4 do 
007  
008 end 

This for loop will create 4 planets and a few moons for each planet.

Step 7

Create a new local variable called planet inside the Init() function:

007 local planet = {x = math.random(50, 200), y = math.random(50, 200)} 

We're making a planet object with a random x and y position.

Step 8

Add the following code to the Init() function:

008 table.insert(planets, planet) 

We'll add the planet object to the planets table in order to draw them later.

Step 9

Create a new local variable called numberOfMoons inside the Init() function:

009 local numberOfMoons = math.random(1, 5) 

We'll add 1 to 5 moons for this planet, making it a random amount for each planet.

Step 10

Create the following Loop:

010 for j = 1, numberOfMoons do 
011  
012 end 

This loop will create each moon object for this planet.

The moon will orbit the planet, so we'll need an origin to rotate around, and an angle and (x, y) offsets to work with polar coordinates.

Step 11

Create a new local variable called moon inside the Init() function:

011 local moon = {x = planet.x, y = planet.y, angle = j * (360 / numberOfMoons), offsetX = 0, offsetY = 0} 

The angles for each moon will be evenly spaced out in (360 / numberOfMoons) increments.

Step 12

Add the following code to the Init() function:

012 table.insert(moons, moon) 

We'll add the moon object to the moons table in order to draw and update them later.

Step 13

Create a new function called Update():

016 function Update(timeDelta) 
017  
018 end

Step 14

Create the following Loop:

017 for k, v in pairs(moons) do 
018  
019 end 

This for loop iterates through every entry in the moons table, giving us the key and value to work within each step.

Step 15

Add the following code to the Update() function:

018 v.angle += angleSpeed 

The angle of this moon object will increase by angleSpeed degrees every time Update() runs.

Step 16

Add the following code to the Update() function:

019 v.angle % = 360 

We don't want the angle to keep increasing infinitely, so we'll use the modulo operation to keep its value to 0 - 359.

Step 17

Add the following code to the Update() function:

020 v.offsetX = moonOrbitRadius * math.cos(math.rad(v.angle)) 021 v.offsetY = moonOrbitRadius * math.sin(math.rad(v.angle)) 

These offsets are the (x, y) representation of the moon object's polar coordinates, calculated by using the formula x = radius * cosine(angle), y = radius * sine(angle). And since math.cos() and math.sin() use radians instead of degrees, we'll need math.rad() to convert the angle to radians

Step 18

Create a new function called Draw():

024 function Draw() 
025  
026 end

Step 19

Add the following code to the Draw() function:

025 RedrawDisplay() 

Step 20

Create the following Loop:

026 for k, v in pairs(planets) do 
027     DrawSpriteBlock(0, v.x - 4, v.y - 4, 2, 2) 
028 end 

We iterate through each planet object in the planets table and draw them using DrawSpriteBlock() because the planet sprite is made up of a 2 x 2 square of sprites, so we need to draw that block of sprites together.

Step 21

Create the following Loop:

029 for k, v in pairs(moons) do 
030     DrawSprite(2, v.x + v.offsetX, v.y + v.offsetY) 
031 end 

We iterate through each moon object in the moons table and draw them using DrawSprite() because the moon sprite is just a single sprite block.