In this tutorial, if code is crossed out like this...
print "Add this line of code"
...it means this line of code will already be there. You only need to add the code in bold. In this part of the tutorial we will be going into the movement of the rocket and the gravity effect. Let start by grabbing a copy of my Corona Template.

function newPlayer(x, y)
local player = display.newGroup()
player.x = x
player.y = y
player.image = display.newImage("sprites/rocket.png")
player:insert(player.image) --Inserts the image into the display group
return player
end
How this works
- Create a new display group within the function
- Move that display group to the x, y coordinates given to the function
- Create a new image from the file we have given.
- Place that image inside the display group
- Returns the display group
--Create a player
player = newPlayer(DISPLAY_W_CENTER, DISPLAY_H_CENTER)
mainScene:insert(player)
So as you can see we are creating a new player using the constants pre-made in the template. These constants are for the center of the screen. We are then storing the player in a variable called player.
This should create our rocket on the screen.


----------------------------------------------------------------
--Buttons
btnRotateLeft = display.newImage("sprites/object_rotate_left.png")
btnRotateLeft.y = 640
btnRotateRight = display.newImage("sprites/object_rotate_right.png")
btnRotateRight.x = btnRotateLeft.width * 1.5
btnRotateRight.y = 640
mainScene:insert(btnRotateRight)
mainScene:insert(btnRotateLeft)
Okay now if we touch these images, nothing happens. We need to add event listeners to them. Add the following code under the buttons.
btnRotateLeft:addEventListener("touch", player.turn)
and
btnRotateRight:addEventListener("touch", player.turn)
What these lines of code are doing is telling the program to look for a touch event on the button. If a touch event is found, it will run the player.turn function. However if you run this now, you will get an error because we do not have a function turn in the player object. So let's create this function now. In the newPlayer function add the following code.
player.turn = function(event)
if event.phase == "began" then
end
end
We now have our function, however both buttons call this function so we need some way to check which button was pressed. To do this we add the following code just below the buttons.
btnRotateLeft.dir = "LEFT"
and
btnRotateRight.dir = "RIGHT"
So your button code should look similar to this.
btnRotateLeft = display.newImage("sprites/object_rotate_left.png")
btnRotateLeft.y = 640
btnRotateLeft.dir = "LEFT"
btnRotateLeft:addEventListener("touch", player.turn)
btnRotateRight = display.newImage("sprites/object_rotate_right.png")
btnRotateRight.x = btnRotateLeft.width * 1.5
btnRotateRight.y = 640
btnRotateRight.dir = "RIGHT"
btnRotateRight:addEventListener("touch", player.turn)
mainScene:insert(btnRotateRight)
mainScene:insert(btnRotateLeft)
Now all we need to do is check in the player.turn function which button was pressed. Inside the event variable there is heaps of information about the event. As you can see we are using phase so the function only runs when the button is first pressed and not again when its released. Another piece of information is target. The target is the button pressed in our case. Each of our buttons have a dir variable so now we can check which button was pressed using event.target.dir. Add the following code straight after the event.phase check.
if event.target.dir == "LEFT" then
else
end
Now all we need to do is rotation the ship left or right. Add the following code.
if event.target.dir == "LEFT" then
player.rotation = player.rotation - 2
else
player.rotation = player.rotation + 2
end
Now, if we run our code and touch the buttons, you will see the ship is now rotating. However its not quiet centered. Add this code to the player function.
player.image.x = player.image.x - player.image.width/2
player.image.y = player.image.y - player.image.height/2
This will move the image so when the ship rotates, it rotates on it's center. Another annoying thing is it's only moving 2 degrees every click. It would be much better if while we were holding the button it would continuously rotate. So lets change our code to implement this.
The first thing we need to do is give the player another variable. Add the following code to the player function.
player.rotating = {false, nil}
This line enables us to do a check to see if the ship should be rotating and by how much. Now in the turn function change
player.rotation = player.rotation - 2
to
player.rotating = {true, -2}
and
player.rotation = player.rotation + 2
to
player.rotating = {true, 2}
Now add and else on the event phase check.
elseif event.phase == "ended" then
player.rotating = {false, nil}
Your full player.turn function should look like this.
player.turn= function(event)
if event.phase == "began" then
local direction = event.target.dir
if direction == "LEFT" then
player.rotating = {true, -2}
else
player.rotating = {true, 2}
end
elseif event.phase == "ended" then
player.rotating = {false, nil}
end
end
The last part of the rotation is to do a check to see if the ship is rotating. This is done in the main loop. Add the following code in the main loop
--Rotate Player
if player.rotating[1] then
player.rotation = player.rotation + player.rotating[2]
end
Now when we click and hold on our buttons. The ship rotates continuously. We are half way there. Now we need to add the movement. First lets limit the ships rotation so it can not turn upside down. Add the following lines of code after we do the rotation in the main loop.
player.rotation = player.rotation + player.rotating[2]
if player.rotation < 270 and player.rotation > 180 then player.rotation = 270 end
if player.rotation > 90 and player.rotation < 180 then player.rotation = 90 end
And finally, so our rotation value does not go into a negative number add these line of code right under the ones you just wrote.
if player.rotation <= -1 then player.rotation = player.rotation + 360 end
if player.rotation >= 360 then player.rotation = player.rotation - 360 end
With these lines of code, if the rotation drops below 0 we add 360 to the rotation to get a true value. Likewise when it raises higher then or equal to 360 we then remove 360.

It is done by using the scale function.
imageName:scale(x,y)
I'll be using this function when I scale this image in code. Lets go ahead and add this button to our screen. Add the following code where you made the rotating buttons.
btnBoosters = display.newImage("sprites/Boosters.png")
btnBoosters:scale(.5, .5)
btnBoosters.y = 640
btnBoosters.x = 1000
btnBoosters:addEventListener("touch", player.fireThruster)
So like before I have added an event listener so when the player touches the image, the function player.startEngine runs. You can also see I have scaled the image to half the x and half the y. Running the code now will cause an error as there is no player.startEngine function. So lets get that one made now. Add the following code inside the newPlayer function.
player.fireThruster = function(event)
if event.phase == "began" then
elseif event.phase == "ended" then
end
end
Now we can run our code and see our button. Here is what is should all look like now.
Okay so lets start our engines. In the fireThrusters function all I will be doing is adding some value to a new variable we are about to make. In the newPlayer function add this line of code.
player.thrust = 0
And now in the fireThrusters function add the following code.
player.fireThruster = function(event)
if event.phase == "began" then
player.thrust = 0.5
elseif event.phase == "ended" then
player.thrust = 0
end
end
Now when we touch the button, our new thrust variable will get a value of 0.5 and when we release our touch it will drop back to 0. Now to add some movement. Add the following variable to newPlayer.
player.velocity = {x=0, y=0}
This will be used to determine how far to move our ship on the x and y axis. We will work on this section one direction at a time. Start by adding a move function to the newPlayer function.
player.move = function()
end
And in the main loop, just after we make our ship rotate, call this new function.
local function main( event )
if player.rotating[1] then
....
....
--Move the Player based on thrust
player.move()
Okay now we need to make the ship move. There are a few sections to this. Lets start by making the ship move when facing straight up. In the move function add the following code.
local angle = player.rotation
if angle == 0 then --Ship Facing Up
player.velocity.y = player.velocity.y - player.thrust
end
When the ship is facing up, we only need to move on the y axis. To do this we simply take the thrust from the y axis velocity. This will make the ship move up the screen when the velocity is applied. To make the ship move add the follow code after what you just entered.
player.y = player.y + player.velocity.y
player.x = player.x + player.velocity.x
These two lines will move the ship based on the velocity. If you run your code now your ship should fly upwards when you hit thrust. However, if you turn the ship, the thrust button will now work. We will add these a little later. Now lets work on when the ship is laying on its left side. In the angle check add the following elseif statement.
player.velocity.y = player.velocity.y - player.thrust
elseif angle == 270 then-- Straight line
player.velocity.x = player.velocity.x - player.thrust
This is almost identical to when facing straight up except we need to take the thrust from the x velocity making the ship move left. Save your code and try it now. You should be able to turn your ship left and it will stop when it is perfectly laid down and thrust. Now lets add this movement when the ship is laid on the right side. Add the follow code, also to the angle check.
player.velocity.y = player.velocity.y - player.thrust
player.velocity.x = player.velocity.x - player.thrust
elseif angle == 90 then-- Straight line
player.velocity.x = player.velocity.x + player.thrust
Now if you test your code the ship should fly when laid on its right side. Okay now we move into the more tricky movements. First lets do when the ship is leaning to the left. First lets add that elseif statement in the angel check. This check need to see if the angle is greater than 270.
player.velocity.y = player.velocity.y - player.thrust
player.velocity.x = player.velocity.x - player.thrust
player.velocity.x = player.velocity.x + player.thrust
elseif angle > 270 then
For this one we need to work out what percentage of that 90 degree section the ship is leaning. Lets for example say the rotation of the ship is 296 degrees.
We need to first find out what the angle is just in that quarter of the angle. So if we take away 270 from the angle we will have the specific angle we need. In our example our angle to work with would be.
296 - 270 = 26 degrees
Now we need to work out what percentage of the 90 degrees the ship has turned through.
26 / 90 = 0.29
The angle we measure has come from the x axis so this number is worked out to find how much thrust to put on the y axis. To get the x axis thrust we simply take this number from 1.
1 - 0.29 = 0.71
To implement this is code add the following lines to the new elseif statement.
angle = angle - 270
local yPercent = angle / 90
local xPercent = 1-yPercent
Now to place the thrust on the x and y velocity we simply add this code.
local yPercent = angle / 90
local xPercent = 1-yPercent
player.velocity.x = player.velocity.x - (player.thrust * xPercent)
player.velocity.y = player.velocity.y - (player.thrust * yPercent)
Save and run your code and you will see you can now fly leaning left. Now lets follow the same procedure and add the ship flying to the right. The difference is because the angle is now measured from the y axis, the first part measures the x axis thrust. Also because the angle is already under 90 we do not have to adjust it. Add the following else statement to your angle checks.
else
local xPercent = angle / 90
local yPercent = 1-yPercent
player.velocity.x = player.velocity.x - (player.thrust * xPercent)
player.velocity.y = player.velocity.y - (player.thrust * yPercent)
Now your ship should fly anyway. However, we don't have any gravity to bring our ship back down. So lets put that in now. Simply add this line right after the if statements we have just been writing and before we add the velocity to the x and y coordinates.
player.velocity.y = player.velocity.y + 0.1
Now your ship should fly up, left and right while being effected by gravity. Now only one more thing to implement. Lets stop our ship from flying off the screen and zero the velocity when it hits the side. Add the following lines of code after we add the velocity to the x and y coordinates.
--Stop the ship flying off the screen
if player.x < 0 + player.width then
player.x = 1 + player.width
player.velocity.x = 0
elseif player.x > DISPLAY_W - player.width then
player.x = DISPLAY_W - player.width
player.velocity.x = 0
end
if player.y < 0 + player.width then
player.y = 1 + player.width
player.velocity.y = 0
elseif player.y > DISPLAY_H - player.width then
player.y = DISPLAY_H - player.width
player.velocity.y = 0
end
Now our ship won't fly off the screen.
Well that's it for now. Keep an eye out for the next tutorial for the moon lander game. Next time we will make the ship crash if we land too hard and maybe add some fuel restrictions.
You can download the code and all the images right here.
No comments:
Post a Comment