Page 1 of 1

2D game - FPS to fast

Posted: Sat Dec 10, 2011 1:19 pm
by DimonSE
Hi all.
I create simple 2d game where 2 airplanes shot each other. Now it's look like this
Image

So in my computer I have FPS=58-61, but in computer of my friend FPS=250 and game is very fast

How I can correct this?

I tried do device->sleep:

Code: Select all

 
while(device->run())
        {
                if (device->isWindowActive())
                {
                        world.time = device->getTimer()->getTime();
 
                        world.ProcessKeyboardEvents(&receiver);
 
                        //Airplanes moved, bullet also moved, fires animate here
                        world.RestructSplines();
 
                        driver->beginScene(true, true, video::SColor(255, 153, 255, 255));
                        
                        smgr->drawAll();
                        world.DrawWorld();
                        device->getGUIEnvironment()->drawAll();
 
                        driver->endScene();
 
                        device->sleep(20-(device->getTimer()->getTime()-world.time));
 
                }
                else device->yield();
        }
 
But it's no look good. Sprites is twitch.

My game in SVN
https://code.google.com/p/irrlicht-2d-a ... aneConcept

My game by arhive
http://irrlicht-2d-airplanes.googlecode ... oncept.rar

Please explain what I can Do???

Re: 2D game - FPS to fast

Posted: Sat Dec 10, 2011 1:37 pm
by Radikalizm
I haven't taken a look at your code, since I just don't have the time to dig through an entire codebase right now, but this just seems like a simple case of framerate dependency
I assume that you are updating your projectiles with a constant translation each frame which causes machines with a faster framerate to have faster projectiles
You need to scale your translation by you frame delta-time to get correct frame-independent movement

Re: 2D game - FPS to fast

Posted: Sat Dec 10, 2011 2:34 pm
by DimonSE
I tried do this, and i have another problem. I save the deltaTime to log file every frame and get this result (time in millisecond):

Code: Select all

16
17
16
17
16
17
16
....
16
68
1
2
1
11
17
16
17
17
16
 
So, when I have deltaTime = 2 or =68 I have twitch of sprites.
Why I have uncorrect deltaTime sometimes?

Re: 2D game - FPS to fast

Posted: Sat Dec 10, 2011 2:52 pm
by Radikalizm
Since I have absolutely no idea of how you're calculating your delta value, I couldn't say ;)

Re: 2D game - FPS to fast

Posted: Sat Dec 10, 2011 4:58 pm
by DimonSE
Sorry :D

First in main() i do this:

Code: Select all

 
while(device->run())
        {
                if (device->isWindowActive())
                {
                        u32 curTime = device->getTimer()->getTime();
                        world.deltaTime =curTime-world.time;
                        world.time = curTime;
 
                        world.ProcessKeyboardEvents(&receiver);
 
                        //Airplanes moved, bullet also moved, fires animate here
                        world.RestructSplines();
 
                        driver->beginScene(true, true, video::SColor(255, 153, 255, 255));
                        
                        smgr->drawAll();
                        world.DrawWorld();
                        device->getGUIEnvironment()->drawAll();
 
                        driver->endScene();
                }
                else device->yield();
        }
 
In main() function I create class World, in constructor of class World I create class Airplane.
In world.ProcessKeyboardEvents I call Airplane->ProcessKeyboardEvents(receiver) where I increate or decreate speed and angle of airplane

Code: Select all

 
if (speed <= SPEED_MAX) speed += AIRPLANE_ACCELERATION * world->deltaTime;

Code: Select all

 
if (angle == 360) angle = 0;
else angle+=ANGLE_ACCELERATION * world->deltaTime;
In world.RestructSplines() I call Airplane->AirplaneFlying();
In AirplaneFlying() I have f32 moving = speed * world->deltaTime and use it value to work with vectors for get new position of airplane.

something like this :D
So, when I have deltaTime near 16-17 mlsec it's look good. But sometimes I have deltaTime = 67 and airplane hight moves, but when deltaTime again 16-17 mlsec airplane back to normal trajectory.
Strange, that every 1-2 second airplane jerk moved i after them back to last position and normal move. Maybe somebody have similar problems?

Re: 2D game - FPS to fast

Posted: Sun Dec 11, 2011 1:55 am
by docWild
Your code is confusing me. It seems like:

Code: Select all

u32 curTime = device->getTimer()->getTime();
                        world.deltaTime =curTime-world.time;
                        world.time = curTime;
You are defining your time variables, one after the other. This defeats the purpose. What you want to do is take the time from the current frame and subtract the time stored from the last frame giving you a difference in time between the two frames. This is the delta value. Try something like this:

Code: Select all

u32 prevTime = device->getTimer()->getTime();
while(device->run())
        {
             u32 curTime = device->getTimer()->getTime();
                if (device->isWindowActive() && (curTime - prevTime) > 100) //arbitrary value, to give you an idea
                {
                   
//do stuff
                    prevTime = curTime; //Set the previous frame to this one.
                 }
//end
 

First of all, by declaring the first variable outside the while loop, it ensures it remains in scope after the iteration finishes. You could also declare the curTime outside the loop, for efficiency, but it must be set before you frame independent actions and your prevTime is only set after the frame independent movement. You are basically calculating application speed by dividing the distance travelled by the time taken (figuratively speaking).

Re: 2D game - FPS to fast

Posted: Sun Dec 11, 2011 9:35 am
by blAaarg
cpp Code: Select all
u32 curTime = device->getTimer()->getTime();
world.deltaTime =curTime-world.time;
world.time = curTime;



You are defining your time variables, one after the other. This defeats the purpose. What you want to do is take the time from the current frame and subtract the time stored from the last frame giving you a difference in time between the two frames. This is the delta value
I presume world.time is being used as "previous time" would be, in which case, this should be correct, although, we can't tell exactly what's happening inside the "world" object.

What looks suspicious to me is:

Code: Select all

if (speed <= SPEED_MAX) 
    speed += AIRPLANE_ACCELERATION * world->deltaTime;
There's a difference between trying to lock down CPU usage and achieving frame rate independence. What this code says is: "if the CPU is running fast (making your deltaTime low), keep going. If the CPU is slowing down, skip some steps until the CPU speeds back up." Thus, the airplane will occasionally change speed.

Generally, if you're using "while(device->run())", you are trying to get as much CPU time as it will give you ( if you're not using sleep() ). In which case, you should update the position of your nodes every frame, and not hide them in an 'if' statement sometimes.

Re: 2D game - FPS to fast

Posted: Sun Dec 11, 2011 11:27 am
by Radikalizm
True, node positions should be updated every frame
Now, it could still happen that your timer glitches up once in a while, you can reduce the effects of this by storing the delta-time values for a couple of frames and take a mean value of these separate values each frame to do your update. This will minimalize the effect of sudden spikes or drops of your framerate, with minimal side-effects

Re: 2D game - FPS to fast

Posted: Sun Dec 11, 2011 5:39 pm
by DimonSE
Ok, I used both ways.

First, I set this code

Code: Select all

 
u32 prevTime = device->getTimer()->getTime();
while(device->run())
        {
             u32 curTime = device->getTimer()->getTime();
                if (device->isWindowActive() && (curTime - prevTime) > 16) //arbitrary value, to give you an idea
                {
                   
//do stuff
                    prevTime = curTime; //Set the previous frame to this one.
                 }
//end
 
for cut deltaTime = near 1-2 millisecond

Second, I use mean value for airplane direction vector. It's mean that airplane moving stabilization.

Thanks all for help me :wink: