Maps and collisions

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
buhb11
Citizen
Posts: 81
Joined: Wed Dec 26, 2012 8:59 pm

Maps and collisions

Post by buhb11 »

Hello lovers!

So i made a couple of games in love2d and every time i end up with the same problem ,maps...Let me explain you better what i mean.I`ve tryied many ways in making a map and apply to it collision but every time i faild.One of the methods i used was making an array like this : map = { 0 , 0 , 1 , 1 } but i dont know how to check if my player hits "1" and then making it stop.I tryied using TileMap but i have the same problem...So i hope you are going to give me an answer because i cant make every game using random terrain generation or linear terrain whitout any platforms. Cheers!
Last edited by buhb11 on Fri May 24, 2013 1:35 pm, edited 1 time in total.
I found Love very enjoyable and nice!
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Maps and collisions

Post by ivan »

The first question I should ask is - is this an action game or is it turn based?
What I'm trying to say is, can player move smoothly on the map or does he move instantaneously between adjacent tiles?
For starters, I think you want a function that converts the player position to tile coords, something like:

Code: Select all

function positionToTile(x, y)
  local tx = math.floor(x/tileWidth + 0.5)
  local ty = math.floor(y/tileHeight + 0.5)
  return tx, ty
end
Things become a little more complicated if this is an action game since you'll have to resolve the collisions in some way.
You'll probably have to iterate all the adjacent tiles and find the "separation" vector so that you can move the player out of the collision.
Therefore, the array would simply be a way to narrow the number of collision checks.
User avatar
buhb11
Citizen
Posts: 81
Joined: Wed Dec 26, 2012 8:59 pm

Re: Maps and collisions

Post by buhb11 »

Right now i am working on a platformer game where my player can move smoothely
I found Love very enjoyable and nice!
User avatar
veethree
Inner party member
Posts: 875
Joined: Sat Dec 10, 2011 7:18 pm

Re: Maps and collisions

Post by veethree »

Collision is pretty simple in theory. Not so much in practice. Basically you check if the player and a tile are overlapping, If so you correct the players position so the overlap no longer occurs.
User avatar
Sheepolution
Party member
Posts: 264
Joined: Mon Mar 04, 2013 9:31 am
Location: The Netherlands
Contact:

Re: Maps and collisions

Post by Sheepolution »

What do you already have?

Can you draw a level like this:

Code: Select all

level = {
1,1,1,1,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,1,1,1,1
}
This should result in a box. Because if you can't do that, then maybe you should start figuring that out.
User avatar
buhb11
Citizen
Posts: 81
Joined: Wed Dec 26, 2012 8:59 pm

Re: Maps and collisions

Post by buhb11 »

Sheepolution wrote:What do you already have?

Can you draw a level like this:

Code: Select all

level = {
1,1,1,1,1,
1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,1,1,1,1
}
This should result in a box. Because if you can't do that, then maybe you should start figuring that out.
Yes i aleardy made something like this before and i assigned a tile to "1" value but i cant figure out how to check collision if my player hits "1" tile
I found Love very enjoyable and nice!
User avatar
Sheepolution
Party member
Posts: 264
Joined: Mon Mar 04, 2013 9:31 am
Location: The Netherlands
Contact:

Re: Maps and collisions

Post by Sheepolution »

Code: Select all

for i=1,#Level.solid.map do
			if Level.solid.map[i] ~=0 then 
				--collision code
				if (collision) then
					break
				end
			end
		end
I'm not sure how far you are, and what you can do. But I want you to try to figure out as much as you can.
User avatar
buhb11
Citizen
Posts: 81
Joined: Wed Dec 26, 2012 8:59 pm

Re: Maps and collisions

Post by buhb11 »

Sheepolution wrote:

Code: Select all

for i=1,#Level.solid.map do
			if Level.solid.map[i] ~=0 then 
				--collision code
				if (collision) then
					break
				end
			end
		end
I'm not sure how far you are, and what you can do. But I want you to try to figure out as much as you can.
Good point!!I couldn't figure out if you didn't show me this piece of code! I am going to work on it right the way!
I am going to use this:

function checkCollision(ax1,ay1,aw,ah, bx1,by1,bw, bh)
local ax2,ay2,bx2,by2 = ax1 + aw, ay1 + ah, bx1 + bw, by1 + bh
return ax1 < bx2 and ax2 > bx1 and ay1 < by2 and ay2 > by1
end

but what i am going to type in bx1 , by1 ?
I found Love very enjoyable and nice!
User avatar
Sheepolution
Party member
Posts: 264
Joined: Mon Mar 04, 2013 9:31 am
Location: The Netherlands
Contact:

Re: Maps and collisions

Post by Sheepolution »

Ah yes.

Let's say the tile we're colliding with is number 7.

Code: Select all

level = {
1,1,1,1,1,
1,[],0,0,1,
1,0,0,0,1,
1,0,0,0,1,
1,1,1,1,1
--We are colliding with [], the 7th tile of the list.
}
So we need to figure out the position of the 7th tile.
To draw the tile on the right place you do something like this right?

Code: Select all

(i % Level.length)*tileWidth --for x
(i/Level.length)*tileHeight -- for y
This is something you can also use for checking the position.
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Maps and collisions

Post by micha »

You are currently mixing up two types of collision: Collision of two objects vs. collision of and object with the map.

What you want right now, is the second type. The code you quote, however, is the first type.

So, here is how I do it:
  • Save the map in a two-dimensional array, as suggested above. E.g.

    Code: Select all

    map = {{1,1,1,1,1},
    {1,0,0,0,1},
    {1,0,0,0,1},
    {1,0,0,0,1},
    {1,1,1,1,1}}
  • Lets assume you are only moving the player (works for any object). The collision detection is integrated into the update. In pseudocode:

    Code: Select all

    given: playerPreviousPosition
    calculatePlayerNewPosition
    if (playerNewPositionCollidesWithMap) then
      adjustPlayerPositionSuchThatCollisionIsResolved
    end
  • How do you check for collision in the "playerNewPositionCollidesWithMap"? That depends on the circumstances. For now, lets assume the player is rectangular and is smaller than one tile. In that case, all you need to check, is if one of the four corners of the player collides with the map. Let's further assume, the player's position is player.x and player.y and it has height and width player.height and player.width. The coordinates are chosen such that each tile has height and width 1. Then you go

    Code: Select all

    indexLeft = math.floor(player.x)
    indexRight = math.ceil(player.x+player.width-1)
    indexTop = math.floor(player.y)
    indexBottom = math.ceil(player.y+player.height-1)
    
    which gives you the indeces of the four corners. Let's say you want to check if the top right corner collides with the map. You go

    Code: Select all

    if map[indexTop] and map[indexTop][indexRight] == 1 then
      collision = true
    end
  • To resolve a collision, if it happens, you need a lengthy if-construction. First check if the player moves left or right. If he moves left, you only need to check the two left corners for collision. If a collision happens, then move the player so far right, that he does not touch the tile anymore.

    Code: Select all

    player.x = math.floor(player.x+1)
    After that do the same for the vertical direction.
This approach is made for the case, where the map is static. If the map moves or you want to have collision detection between moving objects, then you have to adapt it.

Also here are two articles to read, that helped me a lot:
Platform game tutorial at exploding rabbit, covers collision detection in one of the later articles.
The guide to implementing 2D platformers, interesting article. Besides a lot of other stuff, it taught me to decompose movement into x- and y-movment and resolve collision separately.
Post Reply

Who is online

Users browsing this forum: Semrush [Bot] and 187 guests