Need help with BUMP collission resolution
Posted: Tue Feb 28, 2017 3:37 pm
I'm just getting started with BUMP, and while the basics seem straight forward, the documentation leaves a little bit to be desired. Specifically regarding collision types, and collision resolution.
I've got a basic 2d tile-based platformer working, with "slide" as the collision resolution. Of course, "slide" is the default, which is probably the only reason it is working at all. But I also want to have ladders, that use the "touch" collision type. The problem is, I have no idea how to actually define what the collision type is for my ladder-tiles (and the documentation makes no mention of it either). So now the player is just blocked by them, just as with any other wall. So obviously the actual collision type is not being registered at all.
I'm currently handling player movement and collision detection with this code in main.lua, which seems right:
Main.lua:
And I have the following code for the player collision filter in a separate player script:
Playerfunctions.lua:
I then call this function to update the player's position:
I use the following code to add any wall tiles to BUMP as the map is being loaded:
Main.lua:
I suspect the following bit of code is probably crucial:
The above code is how I add my wall tiles to BUMP, and I try to insert the boolean isWall at the end. I'm trying to do the same for ladder tiles, with the difference of adding the boolean isLadder instead. The documentation gives no explanation how to do this, so this is purely me desperately trying to get this to work, and obviously it isn't working.
I've been checking some of the examples that the BUMP documentation refers to, but they all rely completely on the library "middleclass". Which makes it impossible for me to understand how to actually implement collision types without the use of this library. Surely this should be a simple thing to do?
Can anyone help a newb out with this?
I've got a basic 2d tile-based platformer working, with "slide" as the collision resolution. Of course, "slide" is the default, which is probably the only reason it is working at all. But I also want to have ladders, that use the "touch" collision type. The problem is, I have no idea how to actually define what the collision type is for my ladder-tiles (and the documentation makes no mention of it either). So now the player is just blocked by them, just as with any other wall. So obviously the actual collision type is not being registered at all.
I'm currently handling player movement and collision detection with this code in main.lua, which seems right:
Main.lua:
Code: Select all
function movePlayer(playertomove,goalX,goalY,filter)
-- get the collisions
local actualX, actualY, cols, len = world:move(playertomove, goalX, goalY, filter)
--Handle collisions
for i=1, #cols do
local col = cols[i]
print(("col.other = %s, col.type = %s, col.normal = %d,%d"):format(col.other, col.type, col.normal.x, col.normal.y))
end
return actualX, actualY
end
Playerfunctions.lua:
Code: Select all
local playerFilter = function(item, other)
print("Checking collisions...")
if other.isWall or (other.isPlatform and player.Y >= other.y + other.h) then return 'slide'
elseif object.isItem or object.isBullet or object.isEnemy then return "cross"
elseif object.isLadder or object.isZone then return "touch"
elseif object.isLaunch then return "bounce"
else return nil
end
end
Code: Select all
player1.X, player1.Y = movePlayer("Player",(player1.X + player1.speed[1]),(player1.Y + player1.speed[2]),playerFilter)
Main.lua:
Code: Select all
function setupMap() --Set up the map
--The tile sheet
tilesetImage = love.graphics.newImage("/sprites/tiles.png")
collisionReference = {}
collisionReference = loadCollision("/sprites/collisionreference.lua")
--FORMAT: Mapfilename, Scenarioname, swimmers, lifeguards, police, heroes
currentlevel = {"royaltomb", "Royal Tomb"} --1: "Filename", 2: "LevelName"
print("Loading map: "..currentlevel[1])
newlevel = loadMap("maps/"..currentlevel[1]..".lua") --1:background,2:foreground,3:entities
mapWidth = #newlevel[1][1] --tilesetImage:getWidth()/tileSize
mapHeight = #newlevel[1] --tilesetImage:getHeight()/tileSize
print("Mapsize:"..mapWidth*tileSize..","..mapHeight*tileSize)
cameraBounds = {1,1,(mapWidth-(tilesDisplayWidth*zoomlevel)-(tileSize/2)),(mapHeight-(tilesDisplayHeight*zoomlevel))} --42.5,32
mapBounds = {mapWidth,mapHeight}
mapMaxScrollSpeed = 0.5
mapScrollSpeed = mapMaxScrollSpeed
--Here is where we load the map
--Create empty placeholders
map = {}
collisions = {}
--Fill the map with tiles
for x=1,mapWidth do
map[x] = {}
collisions[x] = {}
for y=1,mapHeight do
map[x][y] = (newlevel[1][y][x]) +1 --Copy all background tiles
--Check collision
--"."=nocollision,"x"=wall,"c"=climb,"s"=spike,"w"=water,"l"=lava,"f"=fake,"h"=hidden,"sr"=stairsright,"sl"=stairsleft,"k"=killzone
local tiletype1
local tiletype2
--print("Checking: "..(math.ceil(newlevel[2][y][x] / (tilesetImage:getWidth()/tileSize))).." | "..(tilesetImage:getWidth()/tileSize) - (((math.ceil(newlevel[2][y][x] / (tilesetImage:getWidth()/tileSize)))*(tilesetImage:getWidth()/tileSize))-newlevel[2][y][x]))
if ((newlevel[1][y][x])+1 > 0) then
--(tile )
tiletype1 = collisionReference[math.ceil((newlevel[1][y][x]+1) / (tilesetImage:getWidth()/tileSize))][(tilesetImage:getWidth()/tileSize) - (((math.ceil((newlevel[1][y][x]+1) / (tilesetImage:getWidth()/tileSize)))*(tilesetImage:getWidth()/tileSize))-(newlevel[1][y][x]+1))]
if (tiletype1 == "c") then
--print("Added ladder tile at: "..x..","..y)
end
else
tiletype1 = "."
end
--Normal player collisions
if (tiletype1 == "x" or tiletype1 == "h") then
collisions[x][y] = "x"
local Wallblock = {name="Wall"..(x+(y*mapWidth)-mapWidth),isWall}
addCollision(Wallblock, (x*tileSize), (y*tileSize),tileSize,tileSize)
else
--Check for top of ladder
if (y > 1 and tiletype1 == "c") then
if ((newlevel[1][y-1][x]+1) > 0) then
local tileabove = collisionReference[math.ceil((newlevel[1][y-1][x]+1) / (tilesetImage:getWidth()/tileSize))][(tilesetImage:getWidth()/tileSize) - (((math.ceil((newlevel[1][y-1][x]+1) / (tilesetImage:getWidth()/tileSize)))*(tilesetImage:getWidth()/tileSize))-(newlevel[1][y-1][x]+1))]
if (tileabove == ".") then
--print("Added top of ladder above tile "..x..","..y..", IMAGE: "..(newlevel[1][y][x]+1))
collisions[x][y] = "x"
local Ladder = {name="Ladder"..(x+(y*mapWidth)-mapWidth),isLadder}
addCollision(Ladder, (x*tileSize), (y*tileSize),tileSize,tileSize)
--Also add the ladder interact tile here!
else
collisions[x][y] = "."
local Ladder = {name="Ladder"..(x+(y*mapWidth)-mapWidth),isLadder}
addCollision(Ladder, (x*tileSize), (y*tileSize),tileSize,tileSize)
end
else
collisions[x][y] = "."
end
else
collisions[x][y] = "."
end
end
end
end
end
Code: Select all
local Wallblock = {name="Wall"..(x+(y*mapWidth)-mapWidth),isWall}
addCollision(Wallblock, (x*tileSize), (y*tileSize),tileSize,tileSize)
I've been checking some of the examples that the BUMP documentation refers to, but they all rely completely on the library "middleclass". Which makes it impossible for me to understand how to actually implement collision types without the use of this library. Surely this should be a simple thing to do?
Can anyone help a newb out with this?