## (SOLVED) Newbie problem with dt

General discussion about LÖVE, Lua, game development, puns, and unicorns.
molul
Party member
Posts: 264
Joined: Sun Feb 05, 2012 6:51 pm
Location: Valencia, Spain
Contact:

### (SOLVED) Newbie problem with dt

I'm trying to code a basic tiledbased platformer following this guide and Sonic's Physics Guide (http://info.sonicretro.org/SPG:Running).

My current problem is that I don't seem to be able to handle "dt" properly. If I set or unset vsync in this simple test, the player moves really differently and I don't get why. I use dt in "CHero:updateSpeedX" when adding acceleration or deceleration constant to speed. I thought I should use it in "CHero:updatePosition" too (changing it to self.x = self.x + (self.spX * dt)) but the result is still very different with vsync on and off.

Would someone please tell me what I'm doing wrong? I'd love finally understanding one of my common mistakes. I bet it must be a very basic thing.

Code: Select all

CHero = class:new()

function CHero:init (x, y)
self.x 				= x or 300
self.y 				= y or 210
self.width 			= gTileSize
self.height 		= (2 * gTileSize)
self.edgeX 			= x
self.edgeY 			= y

self.spX 			= 0
self.maxSpX 		= 1000
self.acc 			= 5
self.dec 			= 10
self.friction 		= 5
end

function CHero:update(dt)
self:updatePosition(dt)
end

if (gKeyPressed.left) then
if (self.spX > 0) then
self.spX = self.spX - (self.dec * dt)
elseif (self.spX > -self.maxSpX) then
self.spX = self.spX - (self.acc * dt)
end
elseif (gKeyPressed.right) then
if (self.spX < 0) then
self.spX = self.spX + (self.dec * dt )
elseif (self.spX < self.maxSpX) then
self.spX = self.spX + (self.acc * dt)
end
else
self.spX = self.spX - math.min(math.abs(self.spX), (self.friction * dt)) * math.sign (self.spX)
end
end

-- UPDATE POSITION
function CHero:updatePosition(dt)
self.x = self.x + self.spX
end

--DRAW
function CHero:draw()
love.graphics.setColor(self.color)
love.graphics.rectangle('fill', self.x, self.y, self.width, -self.height)
love.graphics.setColor(255,255,255)
end

Last edited by molul on Wed Feb 17, 2016 7:15 pm, edited 1 time in total.

bobbyjones
Party member
Posts: 728
Joined: Sat Apr 26, 2014 7:46 pm

### Re: Newbie problem with dt

What is the fps with vsync off? If it's 1000 then I would assume that dt wouldn't do much. Dt still affects things. It just makes it less different. I bet if you removed dt completely you would see it move extremely fast at both 1000 and 60 fps. (Also it could be something obvious that I don't see)

Edit 1: when adding your speed to your position you need to use dt. It's in the linear kinetics equation.

Code: Select all

 d = di + vi*t + 1/2a*t^2
--or
d = di + V*t -- this is what you are doing. t is dt. Or should be doing anyways.

Do you frequently have great ideas but immediately lose them? Check out the MVP for my website called IdeaVault. It is designed to solve that problem. Desktop browsers only currently.

molul
Party member
Posts: 264
Joined: Sun Feb 05, 2012 6:51 pm
Location: Valencia, Spain
Contact:

### Re: Newbie problem with dt

Thanks bobbyjones. Fps are more or less 660 with vsync off. Does it make sense that the code is behaving really different from 60 to 660 fps then?
bobbyjones wrote: Edit 1: when adding your speed to your position you need to use dt. It's in the linear kinetics equation.

Code: Select all

 d = di + vi*t + 1/2a*t^2
--or
d = di + V*t -- this is what you are doing. t is dt. Or should be doing anyways.

I'll give it a try again. The problem is, when updating position, the collision detection makes something like

hero.speed = min(hero.speed, closerTileDistance)

as seen in the first link in the OP. I'll try to fix that.

EDIT: adding "dt" to the line where "x" is updated with "speedX" does nothing. With Vsync On it accelerates instantly, while with Vsync Off it slowly builds speed.

I hate it when I can't get to work such a basic thing XD

Tesselode
Party member
Posts: 555
Joined: Fri Jul 23, 2010 7:55 pm

### Re: Newbie problem with dt

Post all your current code so far. It mostly seems right, although...should math.abs(self.spX) (under the else line) be math.abs(self.spX * dt)?

zorg
Party member
Posts: 2942
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

### Re: Newbie problem with dt

To my eyes, the following stood out where dt could have been missing:

Code: Select all

-- UPDATE POSITION
function CHero:updatePosition(dt)
self.x = self.x + self.spX -- from here
end

Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.

molul
Party member
Posts: 264
Joined: Sun Feb 05, 2012 6:51 pm
Location: Valencia, Spain
Contact:

### Re: Newbie problem with dt

Checking all my current code might be a bit tedious. This evening I'll reduce it as much as I can and I'll post it. Thanks for the help so far!

molul
Party member
Posts: 264
Joined: Sun Feb 05, 2012 6:51 pm
Location: Valencia, Spain
Contact:

### Re: Newbie problem with dt

Here's a a simplified version of this test. The problem is the same and there's not as much code to read

EDIT: keys are left and right arrows, and esc to close.
Attachments
platformerTest.zip

Kingdaro
Party member
Posts: 395
Joined: Sun Jul 18, 2010 3:08 am

### Re: Newbie problem with dt

Try this for your update method instead. I notice it could be simplified a bit, and doing that might be a good path towards a solution.

Code: Select all

function CHero:updateSpeedX(dt)
local targetSpeed =
gKeyPressed.left and -self.maxSpX or
gKeyPressed.right and self.maxSpX or
0

self.spX = self.spX + (targetSpeed - self.spX) * math.max(dt * self.acc, 1)
end

It uses a linear interpolation formula to interpolate the player's speed to its max speed, in the direction depending on which key is down. math.max() is used so the speed is guaranteed not to exceed the maximum or minimum speed. In other words, the line says "slowly change this value towards this other value over time".

It doesn't factor in deceleration or friction, but you could probably figure that yourself.

molul
Party member
Posts: 264
Joined: Sun Feb 05, 2012 6:51 pm
Location: Valencia, Spain
Contact:

### Re: Newbie problem with dt

Thanks Kingdaro. This works the same with vsync on or off if I set "self.x = self.x + (self.spX * dt)" in CHero:updatePosition(dt).

However, if possible, I'd like to know what was wrong in my updateSpeed function. I mean, some theory like "you shouldn't use dt here if you already used it there" or "you can't use dt twice in the same function", or something like that. I'm sure I'll find myself in similar situations in the future and I'd like to be able to figure out myself what's wrong

EDIT: ok, I think I figured it out My main problem was that I wasn't using "self.x = self.x + (self.spX * dt)" in CHero:updatePosition(dt). I removed the " * dt" in my full code because, after updating speed and before updating position, I was also checking the closest tile distance, with the final line "hero.speed = min (hero.speed, closestTileDistance)". I have to rework that part.

I tried fixing that problem by adding the line "hero.speed = hero.speed * dt" at the end of the updateSpeed function. That's very wrong, as speed will always be really slow.

Finally, another problem is that I was using very low values for the hero's top speed, acceleration, deceleration and friction.

Thanks for the quick replies everyone. I think I can manage to fix this now ^_^

### Who is online

Users browsing this forum: No registered users and 30 guests