# Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

### Newcomers AppGameKit Corner / Sprite Movement Using Linear Interpolation?

Message
Posted: 28th Jan 2015 00:43
Hello Coders,

Would the use of linear interpolation to move sprites back and forth continously on the X or Y axis offer a more elegant solution for their movement over the use of code that did upper and lower bounds checking and the multiplication of a variable by -1 to change direction?

The formula for interpolation is value1 + (value2 - value1) * amount

Using interpolation would I still need to do bounds checking of some sort?

I'd appreciate a code sample or two to clarify things, thanks.
Posted: 28th Jan 2015 11:55
Are you using V2?
If so, you could create a chain of 2 movement tweens. When GetTweenSpritePlaying() returns 0, apply it again.

There is a full help section on tweens, near the end of the commands section.

Quidquid latine dictum sit, altum sonatur
Posted: 28th Jan 2015 13:39
Quote: "Using interpolation would I still need to do bounds checking of some sort?"

You would only need to make sure amount is between 0 and 1, otherwise you'll extend beyond value1 and value2.

"I like offending people, because I think people who get offended should be offended." - Linus Torvalds
Posted: 30th Jan 2015 22:49
Thanks, guys. I am using AppGameKit V2.

I have had a look at the Tweening section, but a lot of the commands are missing examples written in either BASIC or C++.

To concentrate on linear interpolation for the time being suppose my screen is 1024 on the X axis and 768 on the Y axis and I want to move the sprite smoothly along X from 0 to 1024 I think I'd need to calculate 1 / 1024 which equals 0.0009765625 and use this in a loop to increment amount 1024 times? Am I on the right track?

[ Coding In BASIC using AppGameKit V2 ]
Posted: 31st Jan 2015 00:58 Edited at: 31st Jan 2015 00:59
The other component is time. Your calculation will move 1 pixel per frame. At 60FPS it will take 17 seconds, at 30FPS it will take 34 seconds.

You need

1024.0/T * 1/FPS

Where T is the time to complete the movement.
So if you are running at 60FPS, 30FPS or any other FPS and want to traverse the screen in 2 seconds:

x# = (getVirtualWidth() / 2.0) * (1.0/ScreenFPS())

It is more accurate to save the start time and calculate from that, to ensure you always finish at the right time irrespective of slow frames or inaccurate FPS reporting. In other words, always calculate from the starting point, not from the last point you reached.

x# = (getVirtualWidth() / 2.0) * (1.0/ScreenFPS()) * timeElapsed#

Quidquid latine dictum sit, altum sonatur
Posted: 4th Feb 2015 00:29

I've been doing a bit of experimentation with the following code since your last post.

One thing I noticed is that if I use floats for the X,Y position of the sprite then the vertical edges of the sprites moves slightly when it is in motion. I'm guessing this has to do with the application adjusting the position of where it draws the sprite based upon the value in a float rather than an integer variable.

Option 1 in the code gives me movement at a constant speed, but Option 2 gives me movement with acceleration that keeps increasing until the sprite is a blur - this has to do with the use of ElapsedTime# = Timer().

I had a look at the Timer Based Movements example in the documentation and tried to calculate ElapsedTime# by the following method, but it doesn't work for me because ElapsedTime# never gets beyond something like half a second.

Help and advice for improvement on my methodology very welcome, thanks.

[ Coding In BASIC using AppGameKit V2 ]
Posted: 4th Feb 2015 10:38 Edited at: 4th Feb 2015 10:41
That will teach me to post without checking.

Here is your code, amended to work:

In my example, this:

x# = (getVirtualWidth() / 2.0) * (1.0/ScreenFPS()) * timeElapsed#

should have been this:

x# = (getVirtualWidth() / 2.0) * timeElapsed#

and TimeElapsed is calculated by saving the startTime outside of the loop, and subtracting it from Timer() each loop. you can see this in the amended code above.

In my original 2 options, the first is for timer-based movement. That is, it recalculates the positioning every frame, based on the time it took to execute the previous frame. Sometimes this can be a bit choppy and you won't always reach your destination at the exact time you anticipated. It is used for running around a landscape shooting stuff.
The second example is ideal for you, and the one implemented in the example here. It is a predetermined path with a predetermined finish time. This allows you to plot a smoother path based on the time you started.

Quidquid latine dictum sit, altum sonatur
Posted: 5th Feb 2015 00:03
Thanks again, BatVink.

With reagrds to the sprite flickering I mentioned in my previous post I see that there is a SetSpriteSnap(id, x) to take care of the problem - where x = 1 (snap), or 0 (don't snap) - so my eyes weren't playing tricks on me.

From Page 493 of Hands On AppGameKit Basic:
Quote: "
When a sprite is moving, the theoretical position of the sprite may not map exactly to a pixel. This may cause the sprite to flicker as it adjusts itself to the nearest physical pixel. You can force a sprite to map exactly to a screen pixel by using SetSpriteSanp()
"

[ Coding In BASIC using AppGameKit V2 ]
Posted: 5th Feb 2015 10:05
Quote: "I see that there is a SetSpriteSnap(id, x) to take care of the problem"

Nice find, I wasn't aware of that! That will help some of my creations where I've noticed some flickering.

Quidquid latine dictum sit, altum sonatur
Posted: 5th Feb 2015 21:20
I guess behind the scenes SetSpriteSnap() is casting to an int the float values.

At the moment the command only works with individual sprites, it would be a nice enhancement if it could be applied to all the sprites in an application at once, as it is you'd have to loop through all your spites to set it.

[ Coding In BASIC using AppGameKit V2 ]
Posted: 5th Feb 2015 22:54
BatVink, How do I get the sprite to bounce back and forth between the two sides of the screen?

My ususal method is to check the position of X# and multiply by -1 the amount that is added to X# in order to change direction, in my if statement I've tried this with the variables the program uses, but have had no luck so far.

[ Coding In BASIC using AppGameKit V2 ]
Posted: 5th Feb 2015 23:33
You'll need 2 more variables, one for direction and one for the start position. When you detect the end of a transition, set the direction to 1 or -1, and the start position to the side of the screen you are on. Use these in your movement calculation. Adjusted code below:

Quidquid latine dictum sit, altum sonatur
Posted: 5th Feb 2015 23:49
Nice one, BatVink. It's working perfectly now.

Have yourself a virtual beer on me

[ Coding In BASIC using AppGameKit V2 ]
Posted: 6th Feb 2015 00:13
That was the best way to learn, and can be applied to many other things in AGK. But now I'll show you the easy way (if you have AppGameKit V2)

I used to calculate all my own transitions - movement, fades, resizes, rotates etc. I have a library of linear transitions, ease in and out, berps, ping-pongs, etc etc It's 1,600 lines of code to manage all of these things seamlessly, for as many sprites as needed.

Then Paul made Tweens, and 80% of my code was replaced overnight. I could be bitter, but I'm actually very grateful, it's so much neater.

Here is how you can do the same thing with Tweens. I've used a smooth tween to show how easy it is to improve the look. I've documented the code.

Quidquid latine dictum sit, altum sonatur
Posted: 6th Feb 2015 00:22
Performance wise I assume it is better programming practice to store the value returned by GetVirtualWidth() in an integer variable outside of the do.....loop and use that variable in lieu of the function call itself for calculations within the loop?

[ Coding In BASIC using AppGameKit V2 ]
Posted: 6th Feb 2015 09:44
It probably is, yes, especially as you set the width yourself at the top of the program and already know it.

Quidquid latine dictum sit, altum sonatur