Page 1 of 1
Rectangle/Character Movement: How it works under the hood?
Posted: Wed Jul 01, 2020 6:41 pm
by philfaint
Hello,
sorry for a noobie question, but I've recently started learning game development and got stuck with an issue that I don't understand: why character or any other object movement works gradually. If we take this simple code:
Code: Select all
rectDY = 500
function love.update(dt)
if love.keyboard.isDown('w') then
rectY = rectY - rectDY *dt
elseif love.keyboard.isDown('s') then
rectY = rectY + rectDY *dt
end
end
function love.draw(dt)
love.graphics.rectangle('fill', paddleX, paddleY, 30, 50)
end
the rectangle will gradually move if I press W or S moving smoothly up and down. Now as I see this - update is beng called each frame, thus in case of 60 fps it will be called 60 times. If it's called 60 times, I thought that the rectangle would jump by 500*dt for 60 times per second, like I pressed the button once, it disappeared from initial position, and instantly appeared in a new rectY position - to 500*dt. Instead it slowly and gradually moves up and down, which is correct, but why is it working this way? Can someone please explain me this behaviour? Thank you!
Re: Rectangle/Character Movement: How it works under the hood?
Posted: Wed Jul 01, 2020 11:32 pm
by JJSax
Hello, welcome to the world of Love2d game dev!
dt stands for
delta time. Essentially it is used to move everything more reliable over a period of time, despite if your computer is being laggy at the moment or not. It adjusts for how long it takes a frame to pass.
Code: Select all
speed = 50 -- the number of pixels you want it to move in one second when multiplied by dt
x = 0 -- starting position.
function love.update(dt)
x = x + (speed * dt) -- this will move x to the right by speed number of pixels per second.
end
Re: Rectangle/Character Movement: How it works under the hood?
Posted: Thu Jul 02, 2020 12:30 am
by CogentInvalid
After each call to love.update, the game calls love.draw. So if the game is running at 60 FPS, the rectangle will move 60 times, but each time it moves the screen will redraw and the box will be in a slightly different place. That's why you can see it move gradually - the game doesn't draw the box once every second, it draws it once every frame.
Re: Rectangle/Character Movement: How it works under the hood?
Posted: Thu Jul 02, 2020 1:29 am
by sphyrth
Yes, I'm also re-inventing the Explanation Wheel, but sometimes we can't help it:
First thing because it will mess up the code in your other projects:
REMOVE dt FROM LOVE.DRAW() - That does nothing.
And now...
Exhibit A:
This moves the rectangle 500 pixels per
frame.
Exhibit B:
This moves the rectangle 500 pixels per
second (or at least tries it's best to do so).
Conclusion:
* dt computes for the pixel/second movement regardless of your frame-rate. So it results in a smoother transition. That's so you don't have to do it yourself.
Re: Rectangle/Character Movement: How it works under the hood?
Posted: Thu Jul 02, 2020 11:57 am
by philfaint
thank you for the answers. I guess I understood, but still when I remove *dt from the expression, rect moves smoothly to the desired position. In this case how do I make the rect instantly jump to another position? Like rectY + 500 and stop there? Is there any other key method I need to use for it?
Re: Rectangle/Character Movement: How it works under the hood?
Posted: Thu Jul 02, 2020 3:07 pm
by CogentInvalid
You can put it in love.keypressed if you want it to only move when the player first presses the key, not while the key is held down.
Re: Rectangle/Character Movement: How it works under the hood?
Posted: Mon Jul 06, 2020 4:00 am
by JJSax
philfaint wrote: ↑Thu Jul 02, 2020 11:57 am
thank you for the answers. I guess I understood, but still when I remove *dt from the expression, rect moves smoothly to the desired position. In this case how do I make the rect instantly jump to another position? Like rectY + 500 and stop there? Is there any other key method I need to use for it?
There are a few ways to accomplish that. Depending on exactly what you want it to do. You could just set rectY to the desired location whenever the button is pushed/held. If you're wanting it to stay in a certain range, you're looking for a clamp. I use the
lume library which has a fair few functions I use frequently. If I didn't use the library, I'd use this function. Then you can make it move as fast as you want and it will never go over the maximum value, nor under the minimum value.
Code: Select all
function clamp(number, minimum, maximum)
return math.min(math.max(number, minimum), maximum)
end
for i = 1, 25 do
print(clamp(i, 5, 25)) -- you'll see the printed value stays between 5 and 25
end
Re: Rectangle/Character Movement: How it works under the hood?
Posted: Mon Jul 06, 2020 6:01 am
by ivan
philfaint wrote: still when I remove *dt from the expression, rect moves smoothly to the desired position
*dt doesn't make it smooth, it makes the movement affected by time. This way speed*dt could have consistent/reasonable units across machines. And no, there is no way to ensure that love.update is called at 60 frames per second, otherwise dt would aways be 0.016666 which it isn't