Lua Snippets - Firing Multiple Bullets

This turned out to be a bit more than a small snippet! This example program demonstrates one way you could create multiple bullets by hitting the X button. Has a moveable player as well. The bullets will be created where the player is standing.
First, I will explain each section of code. At the end of the page the entire code will be posted.

Our first bit of code simply creates two color objects to use in our program.

--Create colors green=Color.new(0,255,0)
white = Color.new(255,255,255)
The next section of code will create two blank images, and clear the color of the images to green and white. One image will be our character, the other a bullet. The numbers within the parentheses are the size of the image in pixels (width,height).

--Create a blank image and fill it with green. This will be our bullet. bullet = Image.createEmpty(4,4) bullet:clear(green)
--Create a player.
player = Image.createEmpty(32,32)
player:clear(white)

Now, we will make three variables. oldpad to check for our last button input, cuurentBullet to tell us what the current bullet to be fired is, and direction, which tells us which direction our player is facing.

--Variables
oldpad = Controls.read()
currentBullet = 0
direction = "right"

Next, we will create two arrays. The first simply creates a player array in which we'll store the player's x and y position on the screen. The second array, BulletInfo, looks a bit more confusing so look at it first, and then I'll explain.

--Player Array
Player = {}
Player[1] = { x = 30, y = 100 }

--Create Array for Bullets
BulletInfo = {}
for a = 1,5 do
BulletInfo[a] = { pic = bullet , firing = false, direction = "right", x = Player[1].x + 32,
y = Player[1].y + 16 }
end

The BulletInfo array is storing information just like the player array is.
Notice we used a for loop in this. Since all bullets are going to be made equal we can use this method to define five bullets with less code than doing it one at a time. This loop will create the elements BulletInfo[1], BulletInfo[2], BulletInfo[3], BulletInfo[4], and BulletInfo[5].
Inside each BulletInfo element are five types.
First, we store which image to use for the bullet, and store it in "pic".
Then, we have "firing" which will tell whether or not this bullet is being fired at the moment.
Next is direction, which stores the direction of the bullet. Note that we can't use the player direction variable for this purpose. If we did then each time the player changed directions the bullet would change directions also.
Then we have "x". This will create the bullet at the player's x position plus 32 pixels so that the bullet comes from the edge of the player.
Finally, we have "y". This creates the bullet at player's y position plus 16 pixels so that the bullet comes from about the center of the player.

Let's move to the next section. We will create a function called "bulletSetup()" that will get all the information we need to know. This function will later be called each time "X" button is pressed. It will set up a bullet to use and the position the bullet will get created, as well as direction of the bullet. Look at the code, then I'll detail it.

--Functions
function bulletSetup()
--Increase the current bullet by one, or reset it to 1
if currentBullet < 5 then
currentBullet = currentBullet + 1
else
currentBullet = 1
end
if direction == "left" then
BulletInfo[currentBullet].x = Player[1].x
BulletInfo[currentBullet].y = Player[1].y + 16
end
if direction == "right" then
BulletInfo[currentBullet].x = Player[1].x + 32
BulletInfo[currentBullet].y = Player[1].y + 16
end
if direction == "up" then
BulletInfo[currentBullet].x = Player[1].x + 16
BulletInfo[currentBullet].y = Player[1].y
end
if direction == "down" then
BulletInfo[currentBullet].x = Player[1].x + 16
BulletInfo[currentBullet].y = Player[1].y + 32
end

BulletInfo[currentBullet].direction = direction
BulletInfo[currentBullet].firing = true
end

The first part of the function starts with "if currentBullet < 5 then". This section is saying that if the variable "currentBullet" is less than 5 then increase "currentBullet" by 1. If it is NOT less than 5 then set it to 1. Each time we fire a bullet this code will set a different bullet to use, so that the last bullet fired can still be on the screen.
The next part has four direction checks. These will set the bullets position the minute it gets fired according to the position of the player. Without this our bullet would get created at the right edge of our player regardless of which way he is facing.
Notice we use the "currentBullet" variable to tell the program which BulletInfo element should be used.
The last section sets the direction of the current bullet to the direction of the player. The bullet will keep this direction until it no longer exists. The direction of the bullet will not change if the player's direction changes.
The very last command sets our bullets "firing" to true. This will mean that it IS firing.

Next, we create another function. This function will deal with checking to see if a bullet is firing, and if so, draw it to the screen. Take a look.

function bulletFire()
for i = 1,5 do
if BulletInfo[i].firing == true then
if BulletInfo[i].direction == "right" then BulletInfo[i].x = BulletInfo[i].x + 10 end
if BulletInfo[i].direction == "left" then BulletInfo[i].x = BulletInfo[i].x - 10 end
if BulletInfo[i].direction == "up" then BulletInfo[i].y = BulletInfo[i].y - 10 end
if BulletInfo[i].direction == "down" then BulletInfo[i].y = BulletInfo[i].y + 10 end
screen:blit(BulletInfo[i].x,BulletInfo[i].y,BulletInfo[i].pic)
end
if BulletInfo[i].x < 0 or BulletInfo[i].x > 480 or BulletInfo[i].y < 0 or BulletInfo[i].y > 272 then BulletInfo[i].firing = false end
end
end
Here we used another for loop. The for loop will check BulletInfo elements 1 through 5 and see if their "firiing" is set to true. If it IS set to true, then it checks to see which direction it is set to.
When the direction is found it will increase the bullet's position by 10 pixels in the required direction. Left and right only need the "x" changed, and up and down only need the "y" changed. Once all that information is processed it pastes it to the screen in the correct position with the blit command.
After this, we have some code to check whether the bullet is still on screen or not. If it's "x" position is less than 0 then it's off the screen to the left. If it's "x" position is greater than 480 then it's off the screen to the right. If it's "y" position is less than 0 then it's off the screen at the top. If it's "y" position is greater than 272 then it's off the screen at the bottom.
If it determines that the bullet is off the screen, then it sets that bullets firing to false. This bullet is no longer visible so doesn't need to be set as firing.

I won't go into a lot of detail for the next section. This function will make our player move, and also set which direction he is facing.

function movePlayer()
pad = Controls.read()
if pad:left() then
Player[1].x = Player[1].x - 1
direction = "left"
end
if pad:right() then
Player[1].x = Player[1].x + 1
direction = "right"
end
if pad:up() then
Player[1].y = Player[1].y - 1
direction = "up"
end
if pad:down() then
Player[1].y = Player[1].y + 1
direction = "down"
end
end

Now it's time to get into our main loop. Here's the opener.

--Main Loop
while true do
pad = Controls.read()
screen:clear()

screen:blit(Player[1].x, Player[1].y, player)

if pad:cross() and oldpad:cross() ~= pad:cross() then
bulletSetup()
end

This starts our loop. First, our controls are set up. Then the code to clear the screen each loop is entered.
Next, the code to paste our player to the screen is entered.
This is followed by an "if" statement. This is saying if the "X" button is pressed then perform the bulletSetup() function. The oldpad parts make the code only perform if the button has been released and pressed again since the last time it performed.

For our next code, we will print some information to the screen so that you can see what's going on when you run the program. We will print BulletInfo's firing elements 1 through 5 to the screen. This will tell us which of those bullets is firing. "tostring" converts the information to a string so we can print it. We also print the direction of the player to the screen.

--Print bullet info to screen.
screen:print(10,10,"Bullet 1: ".. tostring(BulletInfo[1].firing),green)
screen:print(10,20,"Bullet 2: "..tostring(BulletInfo[2].firing),green)
screen:print(10,30,"Bullet 3: "..tostring(BulletInfo[3].firing),green)
screen:print(10,40,"Bullet 4: "..tostring(BulletInfo[4].firing),green)
screen:print(10,50,"Bullet 5: "..tostring(BulletInfo[5].firing),green)
screen:print(10,60,"Direction: "..direction,green)

Next we will end up our code and finish the loop.

movePlayer()

bulletFire()

screen.waitVblankStart()
screen.flip()
oldpad = pad
end

The movePlayer() function is called to check for player movement each looop. Then the
bulletFire() function is called each loop to get bullets on the screen if they are being fired.
Then we flip the offscreen buffer to onscreen so that we can see our images.
Then we set oldpad to pad. This is used with checking if the "X" button has been released since the last time it was pressed.
Last we end our loop with "end".

The entire code is below in case you would like to copy it all at once.

--Create colors
green=Color.new(0,255,0)
white = Color.new(255,255,255)

--Create a blank image and fill it with green. This will be our bullet.
bullet = Image.createEmpty(4,4)
bullet:clear(green)

--Create a player.
player = Image.createEmpty(32,32)
player:clear(white)

--Variables
oldpad = Controls.read()
currentBullet = 0
direction = "right"

--Player Array
Player = {}
Player[1] = { x = 30, y = 100 }

--Create Array for Bullets
BulletInfo = {}
for a = 1,5 do
BulletInfo[a] = { pic = bullet , firing = false, direction = "right", x = Player[1].x + 32,
y = Player[1].y + 16 }
end

--Functions

function bulletSetup()
--Increase the current bullet by one, or reset it to 1
if currentBullet < 5 then
currentBullet = currentBullet + 1
else
currentBullet = 1
end

if direction == "left" then
BulletInfo[currentBullet].x = Player[1].x
BulletInfo[currentBullet].y = Player[1].y + 16
end
if direction == "right" then
BulletInfo[currentBullet].x = Player[1].x + 32
BulletInfo[currentBullet].y = Player[1].y + 16
end
if direction == "up" then
BulletInfo[currentBullet].x = Player[1].x + 16
BulletInfo[currentBullet].y = Player[1].y
end
if direction == "down" then
BulletInfo[currentBullet].x = Player[1].x + 16
BulletInfo[currentBullet].y = Player[1].y + 32
end

BulletInfo[currentBullet].direction = direction
BulletInfo[currentBullet].firing = true
end

function bulletFire()
for i = 1,5 do
if BulletInfo[i].firing == true then
if BulletInfo[i].direction == "right" then BulletInfo[i].x = BulletInfo[i].x + 10 end
if BulletInfo[i].direction == "left" then BulletInfo[i].x = BulletInfo[i].x - 10 end
if BulletInfo[i].direction == "up" then BulletInfo[i].y = BulletInfo[i].y - 10 end
if BulletInfo[i].direction == "down" then BulletInfo[i].y = BulletInfo[i].y + 10 end
screen:blit(BulletInfo[i].x,BulletInfo[i].y,BulletInfo[i].pic)
end
if BulletInfo[i].x < 0 or BulletInfo[i].x > 480 or BulletInfo[i].y < 0 or BulletInfo[i].y > 272 then
BulletInfo[i].firing = false
end
end
end

function movePlayer()
pad = Controls.read()
if pad:left() then
Player[1].x = Player[1].x - 1
direction = "left"
end
if pad:right() then
Player[1].x = Player[1].x + 1
direction = "right"
end
if pad:up() then
Player[1].y = Player[1].y - 1
direction = "up"
end
if pad:down() then
Player[1].y = Player[1].y + 1
direction = "down"
end
end

--Main Loop
while true do
pad = Controls.read()
screen:clear()

screen:blit(Player[1].x, Player[1].y, player)

if pad:cross() and oldpad:cross() ~= pad:cross() then
bulletSetup()
end

--Print bullet info to screen. Not needed in your code obviously
screen:print(10,10,"Bullet 1: ".. tostring(BulletInfo[1].firing),green)
screen:print(10,20,"Bullet 2: "..tostring(BulletInfo[2].firing),green)
screen:print(10,30,"Bullet 3: "..tostring(BulletInfo[3].firing),green)
screen:print(10,40,"Bullet 4: "..tostring(BulletInfo[4].firing),green)
screen:print(10,50,"Bullet 5: "..tostring(BulletInfo[5].firing),green)
screen:print(10,60,"Direction: "..direction,green)
movePlayer()

bulletFire()

screen.waitVblankStart()
screen.flip()
oldpad = pad
end


Back To Snippet List

Please welcome stepbrother1988, our newest member.

Who's Online:

Total Members: 844
Total Posts: 13009
Total Topics: 1473
Total Categories: 7
Total Boards: 25

Recent Posts:

Re: chek it out i made front page of qj.net by chi-kitory
Re: chek it out i made front page of qj.net by Rick
Re: Hi everyone (remember me? :P) by Tdude_gamer
Re: Hi everyone (remember me? :P) by dan369
Hi everyone (remember me? :P) by Tdude_gamer
Re: Hows everyone doing? by osgeld
Re: Homebrew Idol 3: The Homebrew Horror Show by dan369
Problem on Tag game by andykd7


Copyright © 2006-2009 www.EvilMana.com All rights reserved.
EvilMana Logo by emcp and Charlie