Sony Playstation Portable Lua Programming: Collision
In this tutorial I will teach you how you can make some simple collisions in lua. This method will use box collision, and will not be pixel perfect collision. Being your first collision attempt, we will keep it fairly simple.

Make A Collision Demo
This small demo that we will make will give us a moveable player. It will also have three blocks on the screen that will have collision implemented for them. The player will not be able to walk through these blocks.

To get started let's create two colors to use. One for our player, and one for our blocks.

green=Color.new(0,255,0)
white = Color.new(255,255,255)
Next, we are going to create new images to use as our player and blocks.
First we create empty 32x32 blocks, and then we will them in with the colors we just created.

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

block = Image.createEmpty(32,32)
block:clear(green)
Now, we need to create an array to hold our Player's information. In this demo it will simply store the player's x and y positions.

Player = { x = 30, y = 100 }
Next, we need to define two variables that will store our player image's height and width. These values will be used in our collision function.
Remember that we created our images 32x32, so those are the values we will use.

playerHeight = 32
playerWidth = 32
Next, let's create an array to store information for the three blocks we are going to make. Naturally, we will store the x and y values for each block so that we have a place to put them on the screen. We will also store the width and height of the blocks into the array. We use the width() and height() commands to do this, which automatically finds those values for us. The values are taken from the block image we created earlier. Let's make it!

Block = {}
Block[1] = { x = 100, y = 80, height = block:height(), width = block:width() }
Block[2] = { x = 300, y = 30, height = block:height(), width = block:width() }
Block[3] = { x = 200, y = 58, height = block:height(), width = block:width() }

Now, let's make a function to move our player around. This will be called every loop to check for movement. It shouldn't be hard to understand if you've followed the other tutorials, so here it is!

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

...and now the juicy stuff. It's now time to create a function that will check if a collision is being made. This function will allow us to check collision for any object we desire in our game, as long as the function is called for that object in our loop. Take a look at the entire function, then we'll break it down.

function collisionCheck(object)
if (Player.x + playerWidth > object.x) and (Player.x < object.x + object.width) and (Player.y + playerHeight > object.y) and (Player.y < object.y + object.height) then
Player.x = oldx
Player.y = oldy
end
end

Take a look at the first line: function collisionCheck(object)
This is creating our function which we named collisionCheck. Notice inside the parentheses we placed the word object. The word is basicly a "dummy" variable. When we actually use our function later we will replace that word with the name of the object we want tested for collision.
If you look inside the function you will notice that the word object appears several more times. When this function gets called all of the object words will be replaced with the actual object we test for.

The second line is dandy don't ya think?!
We have an if statement that is checking for several conditions. Notice that I put each section inside parentheses, which makes a line this long much more readable.
The first check asks (Player.x + playerWidth > object.x).
An images x value is the very top left corner of the image. The whole point of collision is basicly seeing if two images overlap each other, and if so make them stop overlapping. So why do we add the player's width to the player's x value? Simple, because if we only check for the x value of the player then it would not detect collision unless the top left pixel of the image overlaps. If we're moving to the right and there is a block in the way then we need the collision to occur at the right edge of the player image. The player's x value added to the player's width is the top right of the image.
Basicly what we are going to do is create a box area around the image that requires collision. If you enter that box then collision occurs.
I have made some images to let you visualize it as we work through this line of code. The blue box is the still block, and the red box is the player. The black line shows where collision occurs.
So far we have only checked to see if the right side of our player goes past the x value of our other object. Look below.

As you can see, right now our player is inside the collision zone...but we have more checks to do. Next we have (Player.x < object.x + object.width).
This bit of code is for when you're moving left and you hit the right side of the object image. It's basicly reverse from the last bit of code. The object's x value added to it's width will be it's right side. Let's see the collision zone now with the first two checks we have covered.

We are still within the collision zone so far. With those first two checks we have to be between the lines for collision to occur.
Next, we have (Player.y + playerHeight > object.y)
This is for when you're moving down. Player's y position added to the player's height gives us the bottom of the player image. If this value is greater than the other objects y position, then we are colliding. Let's see the image now with 3 checks.


Now, as you see the area above the block no longer is inside the collision zone, since the bottom of player's image has to be greater than the top of the blocks image in order for collision to occur.
Our last check is (Player.y < object.y + object.height)
This part will be for when we move up. If the player's y value is less than the object's bottom (y value added to height) then we are colliding. We use less than this time because moving up on the screen is going down for the y value. Now let's see the image.

Now the bottom lines underneath the block are not collision zones. The only area that is considered colliding now is the area within the block. With our four checks in the if statement we surround the area of the block.
Next, we have to do something once we're inside this area, so we set the player's x and y to oldx and oldy.
We have not defined oldx and oldy yet. We will do so first thing in our main loop. These values will get set to the player's current x and y value at the beginning of each loop. If our function determines that we are inside this collision area then it will set our position back to the last position we were in, which is stored in oldx and oldy. This gives us the illusion of never being able to walk into the block.
The function wraps up after this. I tried to explain this with a lot of detail, so hopefully some of it helped you understand.

Next we get into our main loop. For now I'm going to just paste this code in here. I'm out of time tonight so I will edit to explain it later. It shouldn't be too hard after all we just covered though.

while true do

-- store player's position at beginning of each loop
oldx = Player.x
oldy = Player.y
screen:clear()

movePlayer()

--check collision for each block
collisionCheck(Block[1])
collisionCheck(Block[2])
collisionCheck(Block[3])

--paste player to screen
screen:blit(Player.x,Player.y,player)

--paste all 3 blocks to screen
for a = 1,3 do
screen:blit(Block[a].x,Block[a].y,block)
end

screen.waitVblankStart()
screen.flip()
end


Timers

Please welcome jramada, our newest member.

Who's Online: 7 Guests, 1 User
fret669

Total Members: 555
Total Posts: 13057
Total Topics: 1480
Total Categories: 8
Total Boards: 35

Recent Posts:

Re: Lua Loader? by osgeld
Re: Lua Loader? by acer5050
Re: Lua Loader? by bumuckl
Re: Lua Loader? by acer5050
Re: Lua Loader? by bumuckl
Lua Loader? by acer5050
Re: PGELua Help - need term for a special rotation fix (mathematical issue) by bumuckl
Re: PGELua Help - need term for a special rotation fix (mathematical issue) by tacticalpenguin


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