Page 1 of 1
colliding with STI collision maps with bump.lua?
Posted: Thu Aug 21, 2014 5:24 am
by sam
hi! i was wondering how i would go about making my player collide with STI-loaded collision maps utilizing bump.lua.
i can load in a map (draw it, update it, the whole thing) and i can collide my player with predefined rectangles with bump, but i'm not sure how to go about combining the two.
beginning of main.lua (i'll update this post with the .love file if it's requested). sorry for the messy code!
Code: Select all
local bump = require 'libs/bump'
local sti = require 'libs/sti'
require 'player'
local world = bump.newWorld(32) --new world with 32x32 tiles
local block = {name = "block", --this is the predefined rectangle i was talking about
x = 64,
y = 64,
w = 128,
h = 128
}
function love.load()
map = sti.new('maps/map1')
collision = map:getCollisionMap("solids") --the collision map i would like to collide with
player_load()
world:add(p, p.x, p.y, p.w, p.h) --player hitbox and stuff
world:add(block, block.x, block.y, block.w, block.h) --adding in the rectangle's hitbox
end
collision code (messier!)
Code: Select all
if p.dx ~= 0 or p.dy ~= 0 then
local future_l, future_t = p.x + p.dx, p.y + p.dy
local cols, len = world:check(p, future_l, future_t)
if len == 0 then
p.x, p.y = future_l, future_t
world:move(p, future_l, future_t)
else
local col, tl, tt, sl, st
while len > 0 do
col = cols[1]
if col.other.name == "block" then
tl,tt,_,_,sl,st = col:getSlide()
p.x, p.y = tl, tt
world:move(p, tl, tt)
cols, len = world:check(p, sl, st)
end
if len == 0 then
p.x, p.y = sl, st
world:move(p, sl, st)
end
end
end
end
the part i'm stuck on is writing world:check() for the collision map. if anyone has any pointers, that would be great!
Re: colliding with STI collision maps with bump.lua?
Posted: Thu Aug 21, 2014 8:09 am
by kikito
Hi, I am not familliar with STI, but the bump.lua part of your code looks alright.
the part i'm stuck on is writing world:check() for the collision map
I don't know what 'map:getCollisionMap("solids")' returns. The
documentation says it's "A binary collision map". Not clear enough :/ . The way to do the collisions depends on the way this map is returned.
Can you use
inspect.lua to see what's inside? Download the inspect.lua file to your lib folder, and then:
Code: Select all
local bump = require 'libs.bump'
local sti = require 'libs.sti'
local inspect = require 'libs.inspect' -- new line
function love.load()
map = sti.new('maps/map1')
local collision = map:getCollisionMap("solids") --the collision map i would like to collide with
print(inspect(collision)) -- new line
...
end
That should print the contents of the collision map on the terminal.
Re: colliding with STI collision maps with bump.lua?
Posted: Thu Aug 21, 2014 2:14 pm
by sam
upon inspecting the collision map, i get this- a bunch of data relating to my solids layer.
hope this is compatible!
Re: colliding with STI collision maps with bump.lua?
Posted: Thu Aug 21, 2014 5:40 pm
by kikito
Hi there!
At the end I just gave a look at STI's source code. Taking
Map:drawCollisionMap as a base, here's how you would create the necessary blocks into your empty bump.lua world (this assumes that your world is "ortogonal", not "isometric" or "staggered")
Code: Select all
local function createBlock(world, x, y, tileWidth, tileHeight)
local l, t = (x - 1) * tileWidth, (y - 1) * tileHeight
local block = { name = "block", x = x, y = y } -- , l = l, t = t, w = tileWidth, h = tileHeight --> add these if you want
world.add(block, l,t, tileWidth, tileHeight)
return block
end
local function createBlocksFromCollisionMap(world, collisionMap, tileWidth, tileHeight)
local collisionData = collisionMap.collision
local rows = #collisionData
local cols = #collisionData[1]
local blocks = {}
for x=1,cols do
for y=1,rows do
if collisionData[y][x] == 1 then
local block = createBlock(world, x, y, tileWidth, tileHeight)
blocks[#blocks + 1] = block
end
end
end
return blocks
end
The usage would be:
Code: Select all
function love.load()
map = sti.new('maps/map1')
local collisionMap = map:getCollisionMap("solids") --the collision map i would like to collide with
blocks = createBlocksFromCollisionMap(world, collisionMap, map.tilewidth, map.tileheight)
...
end
It is important to store the blocks in a variable which doesn't get garbage-collected (I've used a global variable called blocks here; it should probably be stored in the same place where you store the reference to your player, for example).
Disclaimer: I have written this code completely from the top of my head, no testing. Expect syntax errors/bugs. But it should give you the right direction.
Re: colliding with STI collision maps with bump.lua?
Posted: Thu Aug 21, 2014 10:53 pm
by sam
thanks for the solution! the only problem i'm having now is that this code -
Code: Select all
local function createBlock(world, x, y, tileWidth, tileHeight)
local l, t = (x - 1) * tileWidth, (y - 1) * tileHeight
local block = { name = "block", x = x, y = y } -- , l = l, t = t, w = tileWidth, h = tileHeight --> add these if you want
world.add(block, l,t, tileWidth, tileHeight)
return block
end
heeds this error -
i couldn't think of what went wrong here (i'm still getting used to lua syntax, haven't used it in a while). i'm not entirely sure how rect is defined, though.
Re: colliding with STI collision maps with bump.lua?
Posted: Fri Aug 22, 2014 7:57 am
by kikito
I wrote world.add instead of world:add. Please try changing that.
Re: colliding with STI collision maps with bump.lua?
Posted: Fri Aug 22, 2014 10:41 pm
by sam
ah, that worked! guess i need to look a little harder from time to time.
thanks for all the help! my only other concern is deleting the blocks that i create. would i make another function similar to createBlocksFromCollisionMap for deleting the blocks?
Re: colliding with STI collision maps with bump.lua?
Posted: Sat Aug 23, 2014 7:10 am
by kikito
hm, you should have told me that you planned to be able to remove the blocks in advance.
First thing you need is to change the way the blocks variable stores blocks.
Code: Select all
local function createBlocksFromCollisionMap(world, collisionMap, tileWidth, tileHeight)
local collisionData = collisionMap.collision
local rows = #collisionData
local cols = #collisionData[1]
local blocks = {}
for x=1,cols do
for y=1,rows do
if collisionData[y][x] == 1 then
local block = createBlock(world, x, y, tileWidth, tileHeight)
blocks[block] = true --> this line is different now
end
end
end
return blocks
end
Then, when you have identified a particular block that you want removed (for example in a collision, it will be collision.other), you can remove it from the blocks table and from the world like this:
Code: Select all
function removeBlock(block, blocks, world)
blocks[block] = nil
world:remove(block)
end
You will probably also need to do something with STI to change the graphic of the map cell. I have no idea about that part.
Re: colliding with STI collision maps with bump.lua?
Posted: Sat Aug 23, 2014 7:46 am
by sam
awesome, man. this solved a lot of my problems. thanks again for taking the time to write out all this code!