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.

AppGameKit Classic Chat / How do I get a sprite to go from point a to point b in the same time regardless of FPS

Author
Message
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 29th Aug 2013 00:16
I know this is supposed to be easy.

Since my WIP is time based for score (mostly), I want to be able to state in my level files the number of seconds for target time for the level. And I want the time it takes to move the sprite from one point to the next to be the same (given constant inputs) regardless of the actual FPS of the device.

I have tried using StepPhysics with desired time frame time multiplied by ratio of desired to actual FPS, and using the same ratio to modify the speed used when setting the velocity or impulse (depending on method used to move).

But I just cannot get it constant.

So, I created a test to try different things and to demonstrate the problem.



It is okay for the times to be different getting the spriteacross the screen for the different methods (velocity vs impulse, selected with the 'V TST' and 'I TST' buttons).

The issue is getting the same time for the different frame rates (selected with the '60FPS' and '30FPS' buttons).

It appears that you cannot get a sprite to move more than 10 pixels per frame.

I am open to advice and suggestions.

Cheers,
Ancient Lady
AGK Community Tester and AppGameKit Master
Marl
12
Years of Service
User Offline
Joined: 19th Nov 2011
Location: Bradford, UK
Posted: 29th Aug 2013 03:10 Edited at: 29th Aug 2013 03:11
Think of everything in terms of seconds and it becomes really easy.

Suppose you want to go from 50,50 to 800,100 and you want it to take 5 seconds.

The distance travelled is 750,50 in 5 seconds or 150,10 in one second.

To apply the change to the sprite on a per-frame basis, you use the value of getFrameTime() multiplied by the speed in pixels per second to get the distance to move.

moveX# = 150 * getFrameTime()
moveY# = 10 * getFrameTime()

Also if you are going to use an FPS value, I would suggest using 1.0 / getFrameTime() to get the exact frame rate for that frame, rather than screenFPS() - which is averaged over several frames.
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 29th Aug 2013 05:37 Edited at: 29th Aug 2013 05:40
I am not using commands like SetSpritePosition to move the sprite. My WIP uses both the methods demoed in my code (based on user play preference) and the Physics Engine to move the player about.

And, as can be seen by running my demo and looking at the difference in the time it takes to cross the screen when the FPS is set to 60 and 30, simply adjusting the value in StepPhysics isn't quite doing what I need.

The issue seems to be a limitation on how far the Physics engine will move a sprite in a single frame. It appears to be capped at 10.

You are correct about how to get a more accurate value for the actual elapsed time in a frame. My demo was going with a simple method. Once the FPS is stabilized (in Windows, anyway), it stays pretty much the same.

Part of my level editor for my WIP lets me set the time for each level and for each movement method. So, in order to set the right time, I test the level on multiple devices in all the methods. But, given a particular straight line and any one device, if the actual FPS is not the same as the target FPS, the time it takes to cross the same amount of space, using the Physics Engine, is not the same.

That is what I am trying to solve.

EDIT: And, in my WIP, you are rarely going in a straight line and the speed you move at is supposed to depend on the method being used to move (each one has a way of deciding what is faster or slower and what direction to move).

The sample I posted is an extremely simplified version of what I do. It uses a bunch of constant values to show the affect on the speed when the actual FPS is not the same as the target FPS.

Cheers,
Ancient Lady
AGK Community Tester and AppGameKit Master
Markus
Valued Member
20
Years of Service
User Offline
Joined: 10th Apr 2004
Location: Germany
Posted: 29th Aug 2013 10:11
i try also, yes its a limit.
maybe you can change the SetPhysicsScale() if you want more.
Marl
12
Years of Service
User Offline
Joined: 19th Nov 2011
Location: Bradford, UK
Posted: 29th Aug 2013 12:43
I'm not sure what you are trying to do by using a target FPS, what if the device will not run at those FPS?

As I said, it is better to think of things in terms of seconds and adjust the movement based on getFrameTime()

Quote: "when the FPS is set to 60 and 30, simply adjusting the value in StepPhysics isn't quite doing what I need."

This is because you are trying to set a target FPS without referencing actual time the frames are taking.

This is not necessary, because the getFrameTime() reflects the actual frame time so basing distance on this will always be adjusted.
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 29th Aug 2013 16:41
Quote: "maybe you can change the SetPhysicsScale() if you want more."

I will definitely give this a try and post whether it helps.

Quote: "I'm not sure what you are trying to do by using a target FPS, what if the device will not run at those FPS?"

There is an optimal appearance of speed that I want to achieve. So, the various object classes in my WIP assume a certain FPS and then adjust based on the actual FPS encountered.

If you want something to have the appearance of the same speed (cross x distance in y time) regardless of FPS (which is what I am trying to accomplish) you must make some assumptions (like target FPS) and adjust based on actual circumstances.

Yes, GetFrameTime() gives the actual one. But, as I said, the code posted above is simplified and, on Windows, it provides values consistent with using GetFrameTime(). And I am using GetFrameTime() in my actual app.

Marl, I am not looking for reasons why I shouldn't be trying to do what I want to do, but how to accomplish it. Over the past 30+ years of programming, I've rarely run into a situation where there isn't some way to get done what I or a client wants done (not that it is always easy).

Cheers,
Ancient Lady
AGK Community Tester and AppGameKit Master
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 29th Aug 2013 19:44
The SetPhysicScale() command was just the right thing.

I was even able to tweak some numbers so that the velocity and impulse methods produce close to the same result. And each has close enough to the same result in both frame rates.

One of the things I observed in my tests is that the SetSpritePhysicsVelocity() pushes the sprite to the top speed almost instantly and then it slows down as it approaches the target (logical because the distance is smaller) and the SetSpritePhysicsImpulse starts off slower and gains speed the longer the 'key' is held down (the affect of repeatedly 'hitting' the sprite).

So, in my WIP, the playing method chosen has a distinct affect on how everything acts.

This is the updated code. The constants used for scale and are set to get a time in the range of 1.8 to 2.0 (roughly) for crossing the entire field at maximum speed for method.


I also tested, via Player, on a device that caps out at 45FPS and I got the same time results as on my Windows box and the other devices tested.

Exactly what I wanted!

It took a bit of playing about to come up with the right value for the physics scale and multipliers for the two methods. But I am happy with the results.

Cheers,
Ancient Lady
AGK Community Tester and AppGameKit Master
Marl
12
Years of Service
User Offline
Joined: 19th Nov 2011
Location: Bradford, UK
Posted: 29th Aug 2013 20:23 Edited at: 29th Aug 2013 20:27
Quote: "Marl, I am not looking for reasons why I shouldn't be trying to do what I want to do, but how to accomplish it."

In which case; here's what I can see in your code;

You have a variable which holds the adjustment step_adj#, which is used to adjust a value based on the current frame rate.

So at 40 fps, a value of 100 (based on 60 fps) would be adjusted to 150 to allow for the lesser frames.

And I think it's here where the problem occurs - it's a question of what value to adjust.

It is used in a couple of places;

1) when you set the velocity of the sprite
2) when you update the physics

I don't think you need to do both.

If the physics is updating for a longer interval (1.5x in the above example), then the sprite will travel proportionally further using the unadjusted Object velocity.

If the Object is travelling faster (1.5x in the above example), then it will travel proportionally further using the unadjusted update time.

EDIT:
NB: The above was a reply to your previous post and older code.
I got reply ninja'd
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 29th Aug 2013 20:51
Marl, yup, that has happened to me as well.

It does turn out that using the SetPhysicsGravity command is crucial to getting the reactions I wanted. The 10 pixel per frame cap on speed (as measured by distance traveled in one frame) was what was killing me. Once I made it the right number, I got exactly what I was looking for.

Cheers,
Ancient Lady
AGK Community Tester and AppGameKit Master

Login to post a reply

Server time is: 2024-05-09 06:37:39
Your offset time is: 2024-05-09 06:37:39