# How to prevent fixed-tile movement

I have a tile-based game with dimensions of 28 x 31 (I'm recreating Mrs. Pacman), and inverted y-axis. The upper-left tile is 1,1 and the lower right is 28,31. Due to the map being very small, I'm scaling it up by 6 times the original size to fit an available screen of 318 x 217 pixels. There is also a character in the game, with a size of 1 x 1 units, so will by 6 x 6 pixels when scaled up (Note: The tiles are only re-scaled when drawn).

Looks like this (You will notice that the width doesn't match that of the actual tilemap, because extra collision is required for the side walls).

The tilemap:

-- 1's are walls; 0's are empty space.

nodemap = {
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1},
{1,1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},
{1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1},
{1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1},
{1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1},
{1,1,1,1,1,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1},
{1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1},
{1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1},
{1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1},
{1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,0,0,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1},
{1,1,1,1,1,0,1,1,1,1,1,0,1,0,0,0,0,0,0,1,0,1,1,1,1,1,0,1,1,1,1,1},
{1,1,1,1,1,0,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,1,0,1,1,1,1,1},
{1,1,1,1,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,1,1,0,1,1,0,1,1,1,1,1},
{1,1,1,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,1,1,1},
{1,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1},
{1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1},
{1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1},
{1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1},
{1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1},
{1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1},
{1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},
{1,1,1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,0,1,1,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1,1},
{1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
}


In order to make the character move with fluidity, it will given a speed of .1. The character will constantly move forwards, will stop upon hitting a wall, and can only turn if there is an empty space in that direction.

The issue I'm having is that when the characters speed is 1, the collision detection is fine, but the movement is ugly; teleporting to the next tile. That's why I gave it a speed of .1, but in doing so, this creates an floating-point index, which messes up the collision.

To counter this, I used the following code to round the characters position based on the decimal:

if (mrspacman.x - math.floor(mrspacman.x) >= .5) then
if (mrspacman.dz == 0 and nodemap[math.ceil(mrspacman.y)][math.ceil(mrspacman.x)+1].id ~= 1) then
moving = true
mrspacman.x = mrspacman.x + mrspacman.speed
elseif mrspacman.dz == 90 and nodemap[math.ceil(mrspacman.y)-1][math.ceil(mrspacman.x)].id ~= 1 then
moving = true
mrspacman.y = mrspacman.y - mrspacman.speed
elseif mrspacman.dz == 180 and nodemap[math.ceil(mrspacman.y)][math.ceil(mrspacman.x)-1].id ~= 1 then
moving = true
mrspacman.x = mrspacman.x - mrspacman.speed
elseif mrspacman.dz == 270 and nodemap[math.ceil(mrspacman.y)+1][math.ceil(mrspacman.x)].id ~= 1 then
moving = true
mrspacman.y = mrspacman.y + mrspacman.speed
end
else
if (mrspacman.dz == 0 and nodemap[math.floor(mrspacman.y)][math.floor(mrspacman.x)+1].id ~= 1) then
moving = true
mrspacman.x = mrspacman.x + mrspacman.speed
elseif mrspacman.dz == 90 and nodemap[math.floor(mrspacman.y)-1][math.floor(mrspacman.x)].id ~= 1 then
moving = true
mrspacman.y = mrspacman.y - mrspacman.speed
elseif mrspacman.dz == 180 and nodemap[math.floor(mrspacman.y)][math.floor(mrspacman.x)-1].id ~= 1 then
moving = true
mrspacman.x = mrspacman.x - mrspacman.speed
elseif mrspacman.dz == 270 and nodemap[math.floor(mrspacman.y)+1][math.floor(mrspacman.x)].id ~= 1 then
moving = true
mrspacman.y = mrspacman.y + mrspacman.speed
end
end


end

This results in some funky behaviour. Does anyone have any ideas to how this can be fixed?