The idea is to have a collision point on the right side of the sprite. Then create a line from the collision point to the next "move" or basically the length of the delta in x -- basically x velocity * dt -- so dx = xVelocity * dt; Then to iterate through that line, if there's no collision add that position onto the sprite's position. If there's a collision then set the sprite's position to align with the tile it's colliding with. (sitting up against it). Having it update the position multiple times through a loop using the move (dx) as the length, was intended to stop tunneling. (I've used swept collision before), however it doesn't seem to be colliding at all for some reason.
And now for some code.
Code: Select all
function CPlayer:MoveRight( map, dx, sx, sy )
--
-- collision point's x value
local x1 = math.floor( sx );
-- a line to the next move
local x2 = math.floor( sx + dx );
local y = math.floor( sy );
local cellX = math.floor( x1 / map.tileWidth );
local cellY = math.floor( y / map.tileHeight );
-- walk the line from x1 to x2
for loopX = x1, x2 do
cellX = math.floor( loopX / map.tileWidth );
local tile = map("Tile Layer 1")(cellX, cellY);
if ( tile ) then
tileType = tile.properties.type;
isBlocked = tile.properties.block_w;
if( tileType == "border" and isBlocked )then
self:SetXPos( (cellX * map.tileWidth) - self:GetWidth() );
else
-- means we can move
currX = self:GetXPos();
-- we only want to add the loop increment value
self:SetXPos( currX + ( loopX - x1 ) );
end;
else
-- we can also move here
currX = self:GetXPos();
-- we only want to add the loop increment value
self:SetXPos( currX + ( loopX - x1 ) );
end;
end;
--
end;
function CPlayer:UpdateHorz( dt, map )
--
local dx = self.velocity:GetX() * dt;
if( dx > 0 )then
xp, yp = self:GetCollisionPointA();
self:MoveRight( map, dx, xp, yp );
end;
--
end;
I just fixed it, using an 'and' instead of 'or'