Page 1 of 2

[Solved]Help With Player Movement

Posted: Tue May 16, 2017 12:16 pm
by uederson
Hi all!
I'm working on a little project for Android.
When I realese a mouse button, I want the player character move 32 pixels and stop.
I'm trying something like the code below (only a example):

Code: Select all

function love.load()
  x,y,z,vel = 0,0,false,100
end

function love.update(dt)
  if z == true then
    if x < y then
      x = x + vel * dt
    else
      z = false
    end
  end
end

function love.mousepressed()
  y = x + 32
end

function love.mousereleased()
  z = true
end

function love.draw(dt)
  love.graphics.print("x: "..x,100,100)
  love.graphics.print("y: "..y,100,150)
end
The issue is that on slow Android smartphones the delta value is higher, then the final value of x sometimes is 33. And if I use a bigger value for "vel", the final value of x is even bigger because of delta.
How to avoid this and have always 32 pixels no matter the vel value on fast and slow smartphones?

Sorry if someone asked this before, but I was unable to find it.

Thank you guys in advance!

Re: Help With Player Movement

Posted: Tue May 16, 2017 1:21 pm
by raidho36
I see you don't intend on free movement, so try "snap" movement with linear interpolation for animation.

Re: Help With Player Movement

Posted: Tue May 16, 2017 3:21 pm
by MasterLee
you x position is the integral of the velocity function, but you are doing integration incorrectly.

Re: Help With Player Movement

Posted: Tue May 16, 2017 5:23 pm
by uederson
raidho36 wrote: Tue May 16, 2017 1:21 pm I see you don't intend on free movement, so try "snap" movement with linear interpolation for animation.
Using your answer as basis, I found the gridlocked player tutorial.
I'm checking it.
Thank you so much!
MasterLee wrote: Tue May 16, 2017 3:21 pm you x position is the integral of the velocity function, but you are doing integration incorrectly.
Can you point me how to do it the right way, pls?

Re: Help With Player Movement

Posted: Tue May 16, 2017 7:37 pm
by airstruck
There's nothing wrong with integration. The problem is that x will always overshoot y unless at the final step, vel*dt is exactly y-x, which would be extremely coincidental.

There are a few ways to fix it. You could simply stick a math.min in there to prevent overshooting. You could use a fixed timestep that agrees with your velocity such that x is guaranteed to be exactly equal to y after some number of iterations. Or you could use a good lerp function which should prevent overshooting, and could be swapped out with an easing function later if you want that sort of effect.

Re: Help With Player Movement

Posted: Wed May 17, 2017 1:08 am
by uederson
airstruck wrote: Tue May 16, 2017 7:37 pm The problem is that x will always overshoot y unless at the final step, vel*dt is exactly y-x, which would be extremely coincidental.
Yes. This is what came to my mind.

Thank you so much, friend!
I dont know yet how to do the things you said, but with your tips (great tips) I know now what I need to do.

Thank you guys by the answers!
As soon as I find a way to fix this, I will be back here to share it.

Re: [Solved]Help With Player Movement

Posted: Wed May 17, 2017 2:37 am
by uederson
The easier way I found for a beginner programmer like me (following the tips airstruck gave me) was using math.min:

Code: Select all

function love.update(dt)
  if z == true then
    if x < y then
      x = x + math.min(vel * dt,32)
    else
      z = false
    end
  end
end
I don't know if this is the best way of solve the issue, but it worked for me!

Thank you again, friends!

Re: Help With Player Movement

Posted: Wed May 17, 2017 9:54 am
by MasterLee
airstruck wrote: Tue May 16, 2017 7:37 pm There's nothing wrong with integration. The problem is that x will always overshoot y unless at the final step, vel*dt is exactly y-x, which would be extremely coincidental.
Exactly what i said with the Integral is wrong.
The position function is desired as following x rises at constant rate over time and then at an timepoint t becomes flat.
The derivate of that the velocity function is simply an step function that start at an constant value and than at an timepoint t goes back to zero.
The derivate of that the acceleration function is the an negative impulse function at timepoint t.
But with the current implementation this impulse is delayed so the whole think becomes wrong.
So the solution is easy simply construct the correct integrals. To do the correct calculation you have to split the functions when you calculate an range that includes t.
This is because you have an discontinuity at t and you can't integrate over discontinuities.

Re: Help With Player Movement

Posted: Wed May 17, 2017 10:24 am
by raidho36
No, airstruck is right, it doesn't matter because you use dt to advance the position, and it's extremely unlikely that whatever dt's you were given would land you at exactly needed destination. Nothing to do with discontinuity, which doesn't even apply since you don't compute integral over acceleration.

Re: Help With Player Movement

Posted: Wed May 17, 2017 1:01 pm
by MasterLee
raidho36 wrote: Wed May 17, 2017 10:24 am No, airstruck is right, it doesn't matter because you use dt to advance the position, and it's extremely unlikely that whatever dt's you were given would land you at exactly needed destination. Nothing to do with discontinuity, which doesn't even apply since you don't compute integral over acceleration.
That is exactly the problem when you land exactly on needed destination no problem would happen. And yes you don't calculate integral over acceleration, but that was only to visualize the problem. When the impulse function is delayed, the step in the step function is also delayed, so the flat part of position function will also reached to late. Which lead to an higher value.