If you're talking about movements that the program does for the user, like those automated slow movements in chess games etc, LERP as they suggested works great. You have a point A and a point B, and the object is traveling between them. LERP is executed with a formula, you should read about it in here:
https://medium.com/swlh/youre-using-ler ... 579052a3c3
Code: Select all
local current_x = point_a.x + (point_b.x - point_a.x) * t
local current_y = point_a.y + (point_b.y - point_a.y) * t
Since 't' should be in the range from 0 to 1, the rate-of-change of 't' controls how fast the object will travel between the points. What should that rate be so that the object travels at a certain fixed speed in pixels per-second? You can find that by getting the distance between the points and dividing by the desired speed in pixels per-second, the result is the rate of change that 't' should have per-second.
Code: Select all
local distance = math.sqrt(
(point_b.x - point_a.x)^2 + (point_b.y - point_a.y)^2
)
local desired_speed = 10 -- (10 pixels per-second)
local rate_of_change = distance / desired_speed
function love.update(dt)
-- Advance t. It slowly changes from 0 to 1.
t = t + (rate_of_change * dt)
-- Check if t reached 1, if so consider the LERP ended.
if t >= 1.0 then
t = 1.0
lerp_is_finished()
end
end
If, however, you're talking about slow movements between tiles
when the object is being controlled by the player, such as with a JRPG game, then you need to do it a bit differently.
You don't know when the player will release the movement key that is making the object move around. When that does happen, the object will either be at a tile center, or be inbetween tile centers.
If you want your objects to always be aligned to tile centers, then when the player releases the movement key you will have to do a
corrective movement, moving the object ahead to the next tile center that's in front of them in the direction that they were traveling.
For this you need some tools, like being able to find out what tile that the object is within. If all tiles are squares then this can be found by taking the object position and dividing it by the length of the tile side.
Code: Select all
-- A tile is a square, I chose the size of 32px x 32px.
local tile_width = 32
local object_tilemap_x = object_world_x / tile_width
local object_tilemap_y = object_world_y / tile_width
From this point you can know a few things:
- (Assuming that you create all objects already centered on tiles)
- Say that object_tilemap_x results in something like "2.73". This means that the player is in column 2 (starting from zero, so it's the third column), and is 73% between the tile centers in the X direction.
- Say that object_tilemap_y results in something like "0.5". This means that the player is in row 0, and is 50% between the tile centers in the Y direction, so they're already centered, vertically.
- The object is within tile [2, 0] (the math.floor() of 2.73 and 0.5), and is moving to the right because the fractional part of object_tilemap_x is bigger than 0.5 (50%) so they crossed the tile center to the right, and are between columns 2 and 3.
To do the corrective movement to place the object on the tile centers of [3, 0], you can do either of these things:
- Use LERP with the fixed speed (fixed rate-of-change) set to the same speed that the object was moving with, so the movement 'feels' the same. The object will travel from tile-center A to tile-center B.
- Use the same movement code that you use for keyboard-controlled movement to keep moving the object in the direction that they were moving, and keep checking every frame if the object crosses tile-center B in that direction. When that happens, snap the object to tile-center B and stop the movement.
Regardless of what method you use, you need to keep track of the object state between frames, like "what they're doing for the time being". You can do this by making use of a finite state machine, which is a way to structure your code so that different actions are clearly separated and can transition from one to the next. I don't know how familiar you are with using a F.S.M., this is an amazing article explaining how it works:
https://gameprogrammingpatterns.com/state.html