1
\$\begingroup\$

In my game I integrate like so: (Please assume all variables to be declared)

sprite.xTimeInSeconds = 5.0; //Time in seconds it should take this object to cross screen
sprite.xVelocity = 1f/xTimeInSeconds;

And then I move it like so:

sprite.gridX+=sprite.xVelocity*dt;         
sprite.x=sprite.gridX*screenWidth;

Then I simply render the sprite at those coordinates:

sprite.draw();  //Uses sprite's internal 'x' which was set above

So, everything within the game itself works fine - ie. all movement is correctly scaled regardless of device, but now I'm trying to write my own swipe/fling touch control system for a menu.

The menu does work - the user can place finger on screen, move up and down and when they release their finger, the menu keeps scrolling(* see below). If they then press their finger down again, the scrolling stops immediately, as one would expect.

The only thing I'm having problems with is how to 'decelerate' the scrolling when the user releases their finger. At the moment, it keeps scrolling at the same speed until it reaches it's limits or the user taps the screen to stop it.

Within my touch-scroll method, I'm simply detemining how much the users finger has moved by and then moving my objects by the same amount. What I need to know (and can't figure out), is how can I - from knowing only the amount of pixels moved, work out the 'time' variable above? (once I have this I can then decelerate at a scaled amount on all devices).

\$\endgroup\$
1
\$\begingroup\$

I may have misunderstood what do you want to do. However, if you know the initial velocity, you can set an acceleration with inverse direction. For example, if velocity is 10 you can set an acceleration -1. Continue to decelerate until the minimum velocity is reached, which is 0. Your velocity will be unlikely to equal 0, so you have to check a change of the signs. If you have acceleration, using Euler method, you can find the velocity. Example:

Velocity = 0.2;

if (........) // Check if the finger is released
{
    Acceleration = -Velocity;
    Acceleration /= abs(Acceleration); // abs returns the absolute value

    Acceleration *= 0.5; // 0.5 is the final magnitude.
}

Position += Velocity * dt;
PrevVelocity = Velocity; // PrevVelocity is needed to check changes in signs
Velocity += Acceleration * dt;

if (PrevVelocity*Velocity <= 0) // if their products are negative, then they
    // have opposite signs
{
    Acceleration = 0;
    Velocity = 0;
}

If you want to calculate the acceleration accurately, you may have to substitute:

Acceleration *= 0.5; // Some random number

with:

Acceleration *= 2/xTimeInSeconds*(distance/xTimeInSeconds-Velocity);

I didn't try this code. I'm not 100% sure that this will work.

\$\endgroup\$
  • 1
    \$\begingroup\$ Hi @Ale thanks, the problem is that initially, because I'm not using integration of any kind to move these objects (they are simply following the user's finger around the screen) - I don't know the time value. That's what I'm trying to work out - the only thing I know for sure is the amount of (physical) pixels that the object has moved. Once the finger is released, I need to work out the 'time' variable so that I can make the object continue to move (using integreation at this point) then slow it down. So the issue I have is that I need to work out the time variable so I can go from there \$\endgroup\$ – BungleBonce Feb 16 '15 at 19:35
  • 1
    \$\begingroup\$ @user22241 Ah. If you are looking for a clock function and you are developing for Android, you may be interested in this: developer.android.com/reference/android/os/SystemClock.html. \$\endgroup\$ – Ale Feb 16 '15 at 19:49
  • 1
    \$\begingroup\$ No @Ale, I'm just trying to find a way to say 'this object is moving 10 pixels per frame, at 60fps, so, my 'time' variable value if I want to move this object using integration would be......' - I'm just trying some calculations to see if I can come up with something again. Sorry, I may not be very clear explaining what I'm after!! :-/ \$\endgroup\$ – BungleBonce Feb 16 '15 at 21:04
  • \$\begingroup\$ @user22241 The way I use to compute dt is to subtract the clock tick of the current frame with the clock tick of the previous frame. I thought that the link would have been useful. \$\endgroup\$ – Ale Feb 16 '15 at 22:05
  • \$\begingroup\$ @user22241 You should do something like: tick = System.currentTimeMillis(); dt = (float)(tick - lasttick) / 1000.0; and at the end of your calculations: lasttick = tick; \$\endgroup\$ – Ale Feb 16 '15 at 22:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.