Rectangle/Character Movement: How it works under the hood?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
philfaint
Prole
Posts: 8
Joined: Wed Jul 01, 2020 6:35 pm

Rectangle/Character Movement: How it works under the hood?

Post 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!
JJSax
Prole
Posts: 47
Joined: Fri Apr 04, 2014 3:59 am

Re: Rectangle/Character Movement: How it works under the hood?

Post 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
User avatar
CogentInvalid
Prole
Posts: 27
Joined: Sat Dec 14, 2013 12:15 am

Re: Rectangle/Character Movement: How it works under the hood?

Post 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.
sphyrth
Party member
Posts: 260
Joined: Mon Jul 07, 2014 11:04 am
Contact:

Re: Rectangle/Character Movement: How it works under the hood?

Post 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:

Code: Select all

...rectY = rectY + rectDY
This moves the rectangle 500 pixels per frame.

Exhibit B:

Code: Select all

...rectY = rectY + rectDY * dt
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.
philfaint
Prole
Posts: 8
Joined: Wed Jul 01, 2020 6:35 pm

Re: Rectangle/Character Movement: How it works under the hood?

Post 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?
User avatar
CogentInvalid
Prole
Posts: 27
Joined: Sat Dec 14, 2013 12:15 am

Re: Rectangle/Character Movement: How it works under the hood?

Post 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.
JJSax
Prole
Posts: 47
Joined: Fri Apr 04, 2014 3:59 am

Re: Rectangle/Character Movement: How it works under the hood?

Post 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
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Rectangle/Character Movement: How it works under the hood?

Post 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
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 2 guests