I have been following a tile based game tutorial (http://www.tonypa.pri.ee/). It's written for flash but I'm trying to translate it into Lua and get it to work with Love too. I'm getting stuck though on tutorial "Hit the Wall". It's technically working but there is some funny behavior when colliding with the right side and the bottom side of my character. The top side and left side collisions are smooth and don't "grab" me or make me stick against the wall when holding in those directions. For example when I'm holding up and left while colliding at the top wall I will still continue to move left. On the other hand when I am moving to the right and down then collide with the right wall, it will grab me and I stop moving down.
I fiddled with the helper functions I wrote thinking I was off by one but that didn't do anything. I have a feeling I'm missing something stupid but figured I'd ask and maybe see the solution as I'm typing or thinking. My thought process for how this should work is that I check the 4 corners of my character. Then I take those 4 corners and look at them through the tile map to see if it is an open space if so we are good to move otherwise stop my movement.
I have also attached the love file and you can move around with the arrow keys. You are the red square and the walls are they grey square.
This is my movement code
Code: Select all
function Hero:move(dx, dy)
local myY = getObjectTileY(self)
--FIX: Shit is still wonky
getCorners(self.x, self.y+dy, self)
if dy < 0 then
if self.upleft and self.upright then
self.y = self.y + dy
else
print('hit top')
self.y = getPixelPositionY(myY)
end
end
if dy > 0 then
if self.downleft and self.downright then
self.y = self.y + dy
else
print('hit bottom')
self.y = getPixelPositionY(myY)
end
end
local myX = getObjectTileX(self)
getCorners(self.x+dx, self.y, self)
if dx < 0 then
if self.downleft and self.upleft then
self.x = self.x + dx
else
print('hit left')
self.x = getPixelPositionX(myX)
end
end
if dx > 0 then
if self.upright and self.downright then
self.x = self.x + dx
else
print('hit right')
self.x = getPixelPositionX(myX)
end
end
end
Code: Select all
function getCorners(x, y, ob)
local obj = ob
obj.x = x
obj.y = y
local downY = getObjectTileBottomMostY(obj)
local upY = getObjectTileTopMostY(obj)
local leftX = getObjectTileLeftMostX(obj)
local rightX = getObjectTileRightMostX(obj)
ob.upleft = map[upY][leftX] == 0
ob.downleft = map[downY][leftX] == 0
ob.upright = map[upY][rightX] == 0
ob.downright = map[downY][rightX] == 0
end
Code: Select all
function getPixelPositionY(y)
return mapY + ((y-1) * tileH)
end
function getPixelPositionX(x)
return mapX + ((x-1) * tileW)
end
function getObjectTileLeftMostX(obj)
return math.floor(((obj.x-mapX)/tileW)+1)
end
function getObjectTileRightMostX(obj)
return math.floor((((obj.x+obj.width+1)-mapX)/tileW)+1)
end
function getObjectTileX(obj)
return math.floor((((obj.x+(obj.width/2))-mapX)/tileW)+1)
end
function getObjectTileTopMostY(obj)
return math.floor(((obj.y-mapY)/tileH)+1)
end
function getObjectTileBottomMostY(obj)
return math.floor((((obj.y+obj.height-1)-mapY)/tileH)+1)
end
function getObjectTileY(obj)
return math.floor((((obj.y+(obj.height/2))-mapY)/tileH)+1)
end