Good Game Loop with Physics Units

Member
Posts: 196
Joined: 2003.10
Post: #1
Hi all,

I'm trying to get back into programming games. I've isolated OpenGL as the source of my woes, and I've gone back to what I started with - Quartz! It's so user-friendly, and so simple to prototype stuff in Obj-C and Cocoa. My plan is to keep the model and controller abstract from the drawcode so that I can someday replace it with OpenGL code. That way I can still have fun while keeping the end-goal of a fast-drawing game alive...

Anyway, on to the beef. I think I've written a good animation loop that calls a physics method based on physics units. It should maintain a solid fps and smooth gameplay, methinks. Comments, please? It's very well commented - should be easy reading:
PHP Code:
- (void)animate:(id)timer
{
    
/* Store Current time to calculate delta time */
    
NSDate *timeOfAnimation = [NSDate date];
    
    
/* Testing for printing of FPS, printing, etc */
    
if ([timeOfAnimation timeIntervalSinceDate:oldFPSTime] > 1.0)
    {
        
NSLog(@"**** FPS: %d ****"frameCounter);
        [
oldFPSTime release];
        
oldFPSTime = [timeOfAnimation retain];
        
frameCounter 0;
    }
    
    
/* Calculate amount of "time" that needs to be animated, persae */
    
currentInterval = ([timeOfAnimation timeIntervalSinceDate:previousAnimationTime]
                        + 
physicsLeftover);
    [
previousAnimationTime release];
    
previousAnimationTime = [timeOfAnimation retain];
    
    
/* Check that no huge amount of time has passed since the last physics event
    was run.  This eliminates jerky movement when client's computer lags */
    
if (currentInterval > (MAX_PHYSICS_UNITS physicsInterval))
    {
        
currentInterval = (MAX_PHYSICS_UNITS physicsInterval);
    }
    
    
/* If the current delta time is long enough to warrant completing a physics unit,
    do so until the current interval is so reduced that it no longer is large enough
    to warrant an entire unit.  Leave the leftover for the next time around the
    animation loop.  Increment the fps counter and draw. */
    
if (currentInterval >= physicsInterval)
    {
        while (
currentInterval >= physicsInterval)
        {
            
currentInterval -= physicsInterval;
            [
self runPhysics];
        }
        
        [
view setNeedsDisplay:YES];
        
        
frameCounter++;
    }
    
    
physicsLeftover currentInterval;

Quote this message in a reply
Member
Posts: 196
Joined: 2003.10
Post: #2
On Keith's advisement (fancy that!) I rewrote a bit of it to get rid of the NSDate objects. No more allocation, deallocation, and a lot fewer square brackets. Hoorah! Code follows:
PHP Code:
- (void)animate:(id)timer
{
    
/* Store Current time to calculate delta time */
    
NSTimeInterval timeOfAnimation = [NSDate timeIntervalSinceReferenceDate];
    
    
/* Testing for printing of FPS, printing, etc */
    
if ((timeOfAnimation oldFPSTime) > 1.0)
    {
        
NSLog(@"**** FPS: %d ****"frameCounter);
        
oldFPSTime timeOfAnimation;
        
frameCounter 0;
    }
    
    
/* Calculate amount of "time" that needs to be animated, persae */
    
currentInterval = ((timeOfAnimation previousAnimationTime) + physicsLeftover);
    
previousAnimationTime timeOfAnimation;
    
    
/* Check that no huge amount of time has passed since the last physics event
    was run.  This eliminates jerky movement when client's computer lags */
    
if (currentInterval > (MAX_PHYSICS_UNITS physicsInterval))
    {
        
currentInterval = (MAX_PHYSICS_UNITS physicsInterval);
    }
    
    
/* If the current delta time is long enough to warrant completing a physics unit,
    do so until the current interval is so reduced that it no longer is large enough
    to warrant an entire unit.  Leave the leftover for the next time around the
    animation loop.  Increment the fps counter and draw. */
    
if (currentInterval >= physicsInterval)
    {
        while (
currentInterval >= physicsInterval)
        {
            
currentInterval -= physicsInterval;
            [
self runPhysics];
        }
        
        [
view setNeedsDisplay:YES];
        
        
frameCounter++;
    }
    
    
physicsLeftover currentInterval;

Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #3
Another interesting way was Keith's multithreaded example, where he runs the physics and graphics independently so one wont slow down the other.

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Member
Posts: 196
Joined: 2003.10
Post: #4
I found that this is one of those fundamental code snippets that either:

a) is out there, but completely complex due to someone trying to squish it down as much as possible
b) is out there, but completely without comments
c) is out there, but not in Objective-C and Cocoa

Might be handy to keep snippets like this in a database on the site...
Quote this message in a reply
Moderator
Posts: 608
Joined: 2002.04
Post: #5
blobbo Wrote:Might be handy to keep snippets like this in a database on the site...
Indeed. It'd be very handy.
Quote this message in a reply
geolycosa
Unregistered
 
Post: #6
you might use CFAbsoluteTimeGetCurrent() instead of NSDate. That returns a much more accurate time (the number of seconds the system has been running).
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #7
Heres a different type of game loop I created for the current game im working on:
Code:
#define FRAMETIME 1/60
while(1) {
    while(t2-t1 > FRAMETIME) {
            t1 += FRAMETIME;
            tick();
        }
        t2 = get_time();
        draw();
    }
}

The aim is to refresh the screen as fast as possible, for strobing effects etc. but to animate the game at a fixed fps, this will also animate several frames if it needs to as well. So a player cant cheat by running somthing in the background to slow the game down.
I think one other possible could be emulation because I hate how emulators slow down so much somtimes.

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  iPhone game loop agreendev 2 4,251 Jul 27, 2010 11:32 AM
Last Post: AnotherJake
  Physics in a Game World mikey 5 4,548 Sep 20, 2009 08:58 AM
Last Post: mikey
  Child Units grazhoper 1 2,660 Sep 2, 2009 12:25 AM
Last Post: AnotherJake
  Trouble with the canonical game loop TomorrowPlusX 27 10,840 Aug 12, 2009 04:22 AM
Last Post: TomorrowPlusX
  Proper game update loop in Cocoa? LoneIgadzra 13 6,641 May 30, 2008 05:49 AM
Last Post: ThemsAllTook