## help with collisions

General discussion about LÖVE, Lua, game development, puns, and unicorns.
bobbymcbobface
Citizen
Posts: 50
Joined: Tue Jun 04, 2019 8:31 pm

### help with collisions

Hi all, i need some help introducing collision and collision detection to my game

things you need you might need to know

my game is top down
i need to allow certain tiles to have collision
i need to detect when a tile is collided with
I'm a complete noob at this and have no idea how collision works but i do have basic love2d knowledge
I make games that run on potatoes :P

pgimeno
Party member
Posts: 1870
Joined: Sun Oct 18, 2015 2:58 pm
Location: Valencia, ES

### Re: help with collisions

My advice: don't try to come up with your own system. Use the built-in Box2D (love.physics) or a library that handles collisions like Bump or HC.

The simplest collision model is that where the colliding shapes are axis-aligned bounding boxes (AABBs). If you can get away with that in your game, then Bump is highly recommended. But if the shapes can be at an angle, or be non-rectangular, Bump won't help you, and you need either Box2D or HC.

Box2D has the advantages that it's in C/C++, that it's integrated with LÖVE, and that it handles collision response automatically (like Bump). The drawbacks are that it's more heavyweight and harder to manage, especially when you prefer cartoonish movement over physically realistic movement. For those cases, you may prefer HC, but IIRC you need to implement the collision response yourself. Fortunately it provides tools for that.

raidho36
Party member
Posts: 1919
Joined: Mon Jun 17, 2013 12:00 pm

### Re: help with collisions

If you want to get a game done, don't reinvent the wheels, find a pre-made tool and use it. If you want to get good, then by all means take your time to reinvent everything, but don't expect to actually make any games any time soon.

Games don't need high quality source code, they just need to function. But not having good programming skills will bottleneck a complicated or computationally intensive project.

bobbymcbobface
Citizen
Posts: 50
Joined: Tue Jun 04, 2019 8:31 pm

### Re: help with collisions

Ok thanks guys

And raidho36 I understand what you mean and I will admit my source code is a bit messy at the moment but in future when I get a better grasp at löve2d I'll fix it up, sure this may cause complications later on in the code but I don't mind re inventing it. Also does one of you or someone mind giving me an example of bump on a top down map since last time I tried it didn't even spawn the bump script

Thank you.
I make games that run on potatoes :P

pgimeno
Party member
Posts: 1870
Joined: Sun Oct 18, 2015 2:58 pm
Location: Valencia, ES

### Re: help with collisions

bobbymcbobface wrote:
Thu Sep 05, 2019 6:35 am
Also does one of you or someone mind giving me an example of bump on a top down map since last time I tried it didn't even spawn the bump script
Not sure what you mean by "spawn" the bump script. There's nothing special about a top-down map when it comes to handling collisions. Any example of bump is good. Some examples will apply gravity to some entities if they are a side view (like platformers) but that doesn't change the idea. You can check the "simpledemo" here: http://github.com/kikito/bump.lua/tree/simpledemo

The main idea of Bump is that every collidable surface is a box. If your map is made of tiles, and the tiles are either fully collidable or not collidable at all, then you just add to the Bump world the rectangles that correspond to the collidable tiles. If they are more complex, with some tiles subdivided into more rectangles, you need some way to store that info in the map, so that you can add each individual rectangle to the Bump world.

bobbymcbobface
Citizen
Posts: 50
Joined: Tue Jun 04, 2019 8:31 pm

### Re: help with collisions

Ok I've had a look at the demo and a look around the internet and unfortunately I'm still extremely confused i understand how bump works (kind of) but I'm having troubles knowing the code for how i would store the data collisions for the map here's the code for my map i need to add collisions to:

Code: Select all

lobby = {}

love.window.setFullscreen(true, "desktop")
TileW, TileH = 32,32

Tileset = love.graphics.newImage('mytileset.png')

local tilesetW, tilesetH = Tileset:getWidth(), Tileset:getHeight()

local quadInfo = {
{ 'o', 64, 0 },
{ 'O', 96, 0},

{ '[', 65, 32 },
{ '{', 65, 64 },

{ '-', 96, 32 },
{ '_', 96, 64 },

{ ']', 125, 32},
{ '}', 125, 64},

{ 'p', 224, 32},
{ ';', 224, 64}
}

for _,info in ipairs(quadInfo) do
-- info[1] = character, info[2]= x, info[3] = y
Quads[info[1]] = love.graphics.newQuad(info[2], info[3], TileW, TileH, tilesetW, tilesetH)
end

local tileString = [[
[----------]p[----------]
{__________};{__________}
ooooooooooooooooooooooooo
ooooooooooooooOoooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooOoooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooOoooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
oooooooooooOooooooooooooo
ooooooooooooooooooooooooo
]]

TileTable = {}

local width = #(tileString:match("[^\n]+"))

for x = 1,width,1 do TileTable[x] = {} end

local rowIndex,columnIndex = 1,1
for row in tileString:gmatch("[^\n]+") do
assert(#row == width, 'Map is not aligned: width of row ' .. tostring(rowIndex) .. ' should be ' .. tostring(width) .. ', but it is ' .. tostring(#row))
columnIndex = 1
for character in row:gmatch(".") do
TileTable[columnIndex][rowIndex] = character
columnIndex = columnIndex + 1
end
rowIndex=rowIndex+1
end
end

function lobby:draw()

for columnIndex,column in ipairs(TileTable) do
for rowIndex,char in ipairs(column) do
local x,y = (columnIndex-1)*TileW, (rowIndex-1)*TileH
love.graphics.draw(Tileset, Quads[char], x, y)
end
end

end

return lobby

--- exit to room needed
--- character needed
---                       |
--- remember to use these V
---                      sprite:move_true()
---                      sprite:draw()

and here's the tile set image:
mytileset.png (8.87 KiB) Viewed 1821 times
Can anyone help me implement it into my code or just give me a nudge in the correct direction
I make games that run on potatoes :P

pgimeno
Party member
Posts: 1870
Joined: Sun Oct 18, 2015 2:58 pm
Location: Valencia, ES

### Re: help with collisions

You create a world first with bump.newWorld(size) (I'll talk about size later). Then right after this line:

Code: Select all

TileTable[columnIndex][rowIndex] = character

you need to check if the character is one of the collidable map elements. If it is, you add the tile to the world. For example:

Code: Select all

world:add({x=columnIndex, y=rowIndex}, (columnIndex - 1)*TileW, (rowIndex - 1)*TileH, TileW, TileH)

That's assuming that your player position will be in pixels. If you wish the positions of your entities (e.g. the player) to be in map coordinates, it would be something like this instead:

Code: Select all

world:add({x=columnIndex, y=rowIndex}, columnIndex, rowIndex, 1, 1)

About size: creating the world with something like twice the size of your rectangles is OK, but take into account that the size of a map rectangle is 1 if you're using map coordinates, and 32 if you're using pixels with TileW=TileH=32.

bobbymcbobface
Citizen
Posts: 50
Joined: Tue Jun 04, 2019 8:31 pm

### Re: help with collisions

ok thankyou pgimeno, so how would i go on about doing this:

"you need to check if the character is one of the collidable map elements."
I make games that run on potatoes :P

pgimeno
Party member
Posts: 1870
Joined: Sun Oct 18, 2015 2:58 pm
Location: Valencia, ES

### Re: help with collisions

One straightforward way is:

Code: Select all

 if character == "collidable_tile_1" or character == "collidable_tile_2" or character == "collidable_tile_3" or ... then

But you can define a table near the beginning instead, which is easier to modify later:

Code: Select all

local collidable_chars = { ["collidable_tile_1"] = true, ["collidable_tile_2"] = true, ... }

...

if collidable_chars[character] then

I'm not sure which characters in your map represent collidable tiles, but assuming for example that 'o' and 'O' are both collidable, one way to start would be:

Code: Select all

local collidable_chars = { ["o"] = true, ["O"] = true, ... }


bobbymcbobface
Citizen
Posts: 50
Joined: Tue Jun 04, 2019 8:31 pm

### Re: help with collisions

Ah thankyou, I'll try this as soon as I get a chance

EDIT: ok i managed to experiment with the code and so far i have this:

Code: Select all

lobby = {}

local sprite = require('sprite')
local bump = require('bump')

sprite:move_true()
--sprite:add_collision({x=columnIndex, y=rowIndex}, columnIndex, rowIndex, 1, 1)

print('map check:')

world = bump.newWorld(32)

TileW, TileH = 32,32

Tileset = love.graphics.newImage('mytileset.png')

local tilesetW, tilesetH = Tileset:getWidth(), Tileset:getHeight()

local collidable_chars = { ["p"] = true, ["p"] = true}

local quadInfo = {
{ 'o', 64, 0 },
{ 'O', 96, 0},

{ '[', 65, 32 },
{ '{', 65, 64 },

{ '-', 96, 32 },
{ '_', 96, 64 },

{ ']', 125, 32},
{ '}', 125, 64},

{ 'p', 224, 32},
{ ';', 224, 64}
}

for _,info in ipairs(quadInfo) do
-- info[1] = character, info[2]= x, info[3] = y
Quads[info[1]] = love.graphics.newQuad(info[2], info[3], TileW, TileH, tilesetW, tilesetH)
end

local tileString = [[
[----------]p[----------]
{__________};{__________}
ooooooooooooooooooooooooo
ooooooooooooooOoooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooOoooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooOoooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
ooooooooooooooooooooooooo
oooooooooooOooooooooooooo
ooooooooooooooooooooooooo
]]

TileTable = {}

local width = #(tileString:match("[^\n]+"))

for x = 1,width,1 do TileTable[x] = {} end

local rowIndex,columnIndex = 1,1
for row in tileString:gmatch("[^\n]+") do
assert(#row == width, 'Map is not aligned: width of row ' .. tostring(rowIndex) .. ' should be ' .. tostring(width) .. ', but it is ' .. tostring(#row))
columnIndex = 1
for character in row:gmatch(".") do
TileTable[columnIndex][rowIndex] = character

if collidable_chars['o'] then
sprite:add_collision({x=columnIndex, y=rowIndex}, (columnIndex - 1)*TileW, (rowIndex - 1)*TileH, TileW, TileH)

end
columnIndex = columnIndex + 1
end
rowIndex=rowIndex+1
end
end

function lobby:draw()
for columnIndex,column in ipairs(TileTable) do
for rowIndex,char in ipairs(column) do
local x,y = (columnIndex-1)*TileW, (rowIndex-1)*TileH
love.graphics.draw(Tileset, Quads[char], x, y)
end
end

sprite:draw()

end

return lobby

--- exit to room needed
--- character needed
---                       |
--- remember to use these V
---                      sprite:move_true()
---                      sprite:draw()
---                      love.graphics.draw(tilesetBatch)

and this doesn't seem to sort out any collsion can someone do some debugging on my code and help me out

also for reference here is the code for sprite:add_collision() :

Code: Select all

function sprite:add_collision(item, x, y, w ,h)
world:add(item, x, y, w, h)
end

thankyou
I make games that run on potatoes :P

### Who is online

Users browsing this forum: Bing [Bot], Sheepolution and 5 guests