Managing dt dependant player position
Posted: Mon Sep 01, 2014 7:27 pm
Good evening, everyone!
Only yesterday I've encountered an annoying problem caused by the delta time update of the player position in my test map, let me explain.
As a premise, I say that the player is moving on an orthogonal tiled map with many layers. The data structure of a layer is substantially a matrix, filled with numbers in each row. I want my player to move only on the zero correspondent tiles in the first layer of the map (just to add more infos, the map is built with Tiled and i'll provide a sample at the end).
Basically, this is the function for my player movement
while the TestMap function needs to check if the player can move (that is, if the position is allowed to update) basing on the nearby tiles, and it's like this:
whereas the various limits are just like
Now, I realized the type of conditions I use in testmap are correct, but still this function can't seem to work at all. The real problem, which I figured out at least, is that since position of the player is dependant from the dt, and I can't have control of it, the limit conditions of which above can't be absolutely right at one pixel precision. As a matter of fact, If I change right_limit to this
that is, now, the player can't walk on a 10 pixel wide stripe, the problem is, almost gone, but still I have some bugs (e.g. diagonal movements or movements caused by weird sequence of input from the user).
Now, I'd like to ask if there's any way to do what I want to do without changing the hell out of the movement system. If my explanation was lacking, please point out where I can explain myself better.
As always, thank you very much for your time in reading my post
PS: attached for the reference is the tiled generated map
Only yesterday I've encountered an annoying problem caused by the delta time update of the player position in my test map, let me explain.
As a premise, I say that the player is moving on an orthogonal tiled map with many layers. The data structure of a layer is substantially a matrix, filled with numbers in each row. I want my player to move only on the zero correspondent tiles in the first layer of the map (just to add more infos, the map is built with Tiled and i'll provide a sample at the end).
Basically, this is the function for my player movement
Code: Select all
function Player.movement(dt)
--there's other stuff here
--delta(x,y) is the normalized vector I use to get the direction my player needs to go (obviously based off the input I receive)
Player.velocity = Player.velocity:len() * delta + Player.acceleration * dt
if Player.velocity:len() > Player.max_velocity then
Player.velocity = Player.velocity:normalized() * Player.max_velocity
end
if Player.TestMap(math.sign(delta.x), math.sign(delta.y), dt) then
Player.position = Player.position + Player.velocity * dt
end
end
Code: Select all
function Player.TestMap(x, y)
nearby_tile_walkable = current_location.data[math.ceil(actual_position.y/tilewidth)+y][math.ceil(actual_position.x/tileheight)+x] ==0
is_at_border = (x==1 and right_limit) or (x==-1 and left_limit) or (y==1 and lower_limit) or (y==-1 and upper_limit)
if not nearby_tile_walkable and is_at_border then
return false
end
return true
end
Code: Select all
right_limit = actual_position.x == last_pixel_of_current_tile
Code: Select all
right_limit = actual_position.x <= math.ceil(actual_position.x/tilewidth)*tilewidth and actual_position.x >= (math.ceil(actual_position.x/tilewidth)*tilewidth)-10
Now, I'd like to ask if there's any way to do what I want to do without changing the hell out of the movement system. If my explanation was lacking, please point out where I can explain myself better.
As always, thank you very much for your time in reading my post
PS: attached for the reference is the tiled generated map