Making my game seem smoother

Nibbie
Posts: 1
Joined: 2010.11
Post: #1
Hi,
I'm running my game on my powerbook G4 667 and I notice that it seems a bit choppy. This shouldn't happen, the game is not too processor intensive, I'm not running other programs. I am attempting to cap the FPS at 60 but it seems to hover around 57-58. I'm not sure exactly why. My shark profile tells me that libSystem.B.dylib's "__gettimeofday" function is taking up 20% of my CPU power. I presume this is because of the way I cap my FPS. The code I'm using to cap it is:

Code:
elapsedTime=0;
while(!(elapsedTime>MAX_FPS)) elapsedTime = (SDL_GetTicks() - lastFrameTime) / 1000.0f;
MAX_FPS #define'd to 1.0f/60.0f.

The game is not slow, but the animation/movement is just a tad jerky when it should be smooth. I am frusterated that some games run 20fps and look smoother than mine. I have VBL syncing on:
Code:
#ifdef __APPLE__
        long VBL = 1;
        CGLSetParameter(CGLGetCurrentContext(),  kCGLCPSwapInterval, &VBL);
#endif
on the Mac builds. It's not helping. I can't compare against the Windows builds because I havn't managed to port all of the game yet.

All movement is time based. For example instead of x=x+1; it's x=x+1*elapsedTime;
This way if the game can only run 20fps it runs fine at 20fps instead of 1/3 the speed. I might be doing something really inept with this Rasp

Does anyone have any idea what I might be doing wrong? What might fix this?

Thanks Smile
Quote this message in a reply
Moderator
Posts: 529
Joined: 2003.03
Post: #2
Joseph Duchesne Wrote:All movement is time based. For example instead of x=x+1; it's x=x+1*elapsedTime;

That will almost definitely make it jerky.

You need to decide on a fixed time step (1/100th of a sec, 1/60th...whatever). Divide elapsed time by that step and run the physics that many times in a for loop or some such, then draw.

Or refer to Alex's excellent tutorial: http://sacredsoftware.net/tutorials/Anim...tion.xhtml

"Yes, well, that's the sort of blinkered, Philistine pig-ignorance I've come to expect from you non-creative garbage."
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #3
Leisure Suit Lurie Wrote:
Joseph Duchesne Wrote:All movement is time based. For example instead of x=x+1; it's x=x+1*elapsedTime;
That will almost definitely make it jerky.

Time based is a good way to stop movment being jerky, if your running the physics on a fixed time step it will be more deterministic but when things get complicated you will see things slow down and speed up.

I think the way your capping the fps is a causing the problem
your going to be repeatedly calling SDL_GetTicks() which is really not a good idea, just redraw the screen but dont animate anything then recheck your frame time and see if you need to update the physics again.

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Member
Posts: 33
Joined: 2002.04
Post: #4
Generally speaking there will be no visual jerkiness as a result of using fixed/variable interval based animation, because the state of the world when it's rendered is all you see anyway. So this part should be fine: "All movement is time based. For example instead of x=x+1; it's x=x+1*elapsedTime"

You do not need to cap your frame rate manually because you have vbl sync enabled (which is good), and stalling will be performed whenever you swap frame buffers (such as a call to glFlush() or SDL_GL_SwapBuffers()). Here's a crunched together update loop I use:

Code:
#define USE_FIXED_INTERVAL_UPDATING 1
#define        kUpdateInterval            8 //8 ms per update = 125 updates per second

//Update function expects number of seconds as float
float delta, updateValue = kUpdateInterval / 1000.0f;
Uint32 lastTime = SDL_GetTicks(), time, workingTime = 0;
while ( !done )
{
    
    lastTime = time;
    
    time = SDL_GetTicks();
    delta = time - lastTime;       //Compute change in time for this frame
        
#ifdef USE_FIXED_INTERVAL_UPDATING
        workingTime += delta;    //add it to running total of update time we can work with
        delta = 0;
        while(workingTime >= kUpdateInterval)
        {
            workingTime -= kUpdateInterval;
            delta += kUpdateInterval;    //Update deltas need to be calculated from what is actually used
            game->Update(updateValue);
        }
#else    //USE_VARIABLE_INTERVAL_UPDATING
            //Update locations and what nots for the given amount of time
            updateValue = delta / 1000.0f;
            game->Update(updateValue);
#endif
game->Draw();
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #5
What Nickolei said. Don't ever manually limit your frame-rate (particularly not with a spin-loop); rely on VBL sync to do it for you.

If you're not making frame-rate, having VBL sync on can cause jerkiness. For Outnumbered, I turn it off if that seems to be happening, and that seems to work OK.
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #6
Yeah, repeatedly getting the time in tight while loop is not a good idea. If you need to "waste" some time until the next frame, don't burn it up in a loop, call some sort of wait or sleep function. That way your program won't use any CPU while it's waiting for the next frame. That's what I do, and it seems to work really well.

Be warned of a couple of things though, don't have your program pause and then have to wait for the VBL sync. So swap your buffers and then wait out the rest of the time. Also, the scheduling is pretty coarse, asking for a sleep time of less than 10ms will probably still sleep for 10ms.

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Post Reply