After the last post I’ve been working on the mechanic that gives name to the project: Landing. It took me some time to get it right, but finally it is implemented!
After a collision of the ship against the planet is detected, the game checks if the speed of the ship is higher than the maximum value that it should have while landing, and if its higher than that, the ship is destroyed.
Now, if the ship’s speed is lower than this maximum value, the ship lands and is not destroyed. This means:
Until now, the ship was in it’s state 1, “Flying”:
Only in this state, the ship is affected by gravity, can be accelerated forward and rotated by the player and can be considered or not as a “collidable” object. (A collision can be detected against the planet or not).
Now the ship transitions to state 2, “Landing”:
In this state, the length and the angle of the line that goes from the center of the planet (The center of the screen) to the center of the ship are calculated, and the ship is moved to an specific distance from the center of the planet. I did this because in my first experiments with landing, the ship always ended being more or less “inside” of the planet after a collision, depending on the speed that the ship had when the collision happened. Now I make sure that the ship is always at the exact same distance from the center of the planet, independently of any variable. The speed of translation and the speed of rotation are made 0 and we…
Go to state 3, “Rotating”:
This part took me some time to complete. After the ship lands, it should be at a certain angle, depending on the point on the surface where it landed, so the ship is always “pointing” outwards the planet.
The problem is that the landings wont always be perfect. I could punish the player and destroy the ship if it lands at a weird angle, but I thought that doing that would make the game unnecessarily frustrating. I decided that the ship should slowly rotate to its right position.
The rotation itself wasn’t the difficult part, but making the program being able to decide if the rotation should be clockwise or anti-clockwise, depending on which one would take less time to complete, took me some time and effort.
After a while, I came up with this:
self.rotation is the angle of rotation of the ship.
self.angleC is the angle of the line that goes from the center of the planet (The center of the screen) to the center of the ship.
yS is the “y” coordinate of the center of the ship, relative to the center of the planet.
And the reference system:
Notice how the positive values of “y” are under the “x” axis.
In the quadrants I and II the angles take positive values (From 0 to Pi, right to left), and in quadrants III and IV, negative values (From -Pi to 0, left to right).
Well, after observation of all the different possible positions of the angles in all the different quadrants, I discovered that:
If the ship’s “yS” is positive, we have that if the difference self.rotation – self.angleC is negative (self.angleC > self.rotation) AND the absolute value of that same difference is less than pi (One angle is not more than 180 degrees away from the other), the rotation should be Clockwise.
If the ship’s “yS” is negative, we have that if self.rotation – self.angleC is now positive (self.rotation > self.angleC) AND the absolute value of that same difference is less than pi, the rotation should be ANTI-Clockwise.
With this information I wrote the algorithm:
elseif self.state == 3 then--IF IN ROTATING STATE.
local angleSSubC = self.rotation - self.angleC
local maxDif = pi / 32
--If there is too much difference between angles.
if math.abs(angleSSubC) > maxDif then
--Determine if ship should rotate clockwise or anti-clockwise:
if yS >= 0 then
if angleSSubC < 0 and math.abs(angleSSubC) < pi then
self:rotate(dt, 3) --Clockwise
else
self:rotate(dt, -3) --Anti-Clockwise
end
else
if angleSSubC > 0 and math.abs(angleSSubC) < pi then
self:rotate(dt, -3) --Anti-Clockwise
else
self:rotate(dt, 3) --Clockwise
end
end
else --If the ship is already in the correct angle.
self.state = 4 --TO TAKING-OFF STATE.
end
"self:rotate(...)” will be called until the absolute value of the difference “self.rotation - self.angleC” is smaller than the maximum difference of “pi / 32″. After the rotation is done, the game switches to the...
Here the ship just waits for input. If the player presses the “accelerate” key, the ship becomes “non-collidable” (A collision against the planet wont be detected) and goes back to state 1, where it accelerates (As long as the player keeps pressing the button associated to the acceleration) its way out of the surface of the planet and becomes “collidable” again when it stops being in contact with it.
Well, I hope some of this made sense for you. Now, I am working on the sound effect “engine”.
...Is “collidable” even a real word?