iDevGames Forums
Game Timing (Cocoa) - Printable Version

+- iDevGames Forums (
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Game Programming Fundamentals (/forum-7.html)
+--- Thread: Game Timing (Cocoa) (/thread-7692.html)

Game Timing (Cocoa) - Fletch - Jun 23, 2002 11:51 AM

I'm just starting to work on my first OpenGL game (a humbling little tetris clone or something). The problem is that there's one thing I don't know how to do yet, and that's to give the game some kind of heartbeat I can use to regulate animations/gameplay.

I'm looking for a simple way to make the game tick every millisecond or ten for my main loop. Can somebody help me out?

I'm using C in project builder, like the Nehe OS X examples.


Game Timing (Cocoa) - GoodDoug - Jun 24, 2002 10:52 AM

Check out NSTimer. It has what you want.

Game Timing (Cocoa) - kainsin - Jun 24, 2002 12:13 PM

I wouldn't use a timer based animation method for 3D animation, especially OpenGL. Since OpenGL ( and other 3D rendering API's ) only draw on the scan lines, you are guaranteed to not draw more than the monitor can handle.

Instead, when you want to draw one frame of animation, check to see how much time has passed. You can use the Carbon function Microseconds to accomplish this:

void Microseconds( UnsignedWide *microseconds );

Or if you don't want to use Carbon functions and want to leave it ANSI compatible then try:

include <sys/time.h>

int32_t GetMicroseconds( void ) { // int32_t is just an 'int' on PPC systems but that may change.

timeval returnValue;

gettimeofday( &returnValue, NULL );

return returnValue.tv_usec;

What's the point of seeing just how long it's been since the last frame of animation? Well, if you want the object to move 1.0 units in 1 second, all you have to do is see how far it needs to have moved since the last frame of animation ( # of milliseconds ) and divide the amount you want it to move in one second by that amount.


#define kMillisecondsPerSecond 1000000   // 1 million, this is prolly defined elsewhere
unsigned long lastFrameTime, currentFrameTime;

currentFrameTime = Milliseconds();

float distanceAlongXAxis = kXAxisMovementPerSecond /
    ( ( currentFrameTime - lastFrameTime ) * kMillisecondsPerSecond );

// Do this for y-axis ( and z-axis if 3D ) as well.

Now you may think that this will run too fast on faster machines, but this is not the case. Since this will only move the object a percentage of it's total movement in one second depending on how long the last frame has taken to draw, faster machines will only yield smoother animations. Hence the desired "high frame rates".

Side Note: You may want to check to make sure that currentFrameTime != lastFrameTime otherwise you'll end up having a divide-by-zero error. But if you have a computer set up to render anything even remotely difficult in zero-milliseconds then you are indeed 'The Man'.

Game Timing (Cocoa) - OneSadCookie - Jun 24, 2002 01:28 PM

Two things:

gettimeofday is not ANSI, but POSIX.

tv_usec wraps back to 0 from 999999 every second, so you really want:

double getCurrentTime()
    struct timeval time;
    gettimeofday(&time, NULL);
    return (double)(time.tv_sec) + (double)(time.tv_usec) * 0.000001;

which returns the time as a double, where 1.0 is one second.

Game Timing (Cocoa) - Fletch - Jun 25, 2002 07:49 AM

I see,

That's great. I'll try these out and see how well it works for me. Thanks for all the help!

Game Timing (Cocoa) - Feanor - Jun 25, 2002 10:21 PM

Sorry to be contradictory, kainsin, but while you certainly want to be careful with your animation stepping, in a Tetris-style game, I don't imagine it's going to be necessary to have accurate timing of frame-drawing, since the frames will probably be drawn very, very fast.

There is no visibility culling, little or no depth sorting, probably no multi-pass rendering or anything else complicated, and on the order of a hundred polygons or less (more if the entire user-interface is done with OpenGL). The frame-rate unthrottled would probably be 100 or 200 fps or something. Most Tetris games don't even bother to animate the blocks smoothly, though -- they happily skip them forward exactly the size of a block, so only updating the screen when the animation steps are done would be perfectly acceptable.

You could probably set the speed of the game by the speed of the timer and leave it at that. Initially every half or two-thirds of a second between steps, and then a bit faster for each successive level of difficulty.

Now, if we're going to have smooth sliding left, right and down, and smooth rotations, that's a whole different thing :o).


Game Timing (Cocoa) - OneSadCookie - Jun 26, 2002 03:09 AM

You do still have to be a little careful, particularly if you're targeting OS9, but on either 9 or X it's possible to lose significant amounts of time to other processes, so you always have to be prepared to miss a frame.

What you choose to do in that situation, of course, is your own decision to make. For tetris, I'd probably be inclined to ignore it Smile

Game Timing (Cocoa) - Fletch - Jun 26, 2002 08:44 AM


Correct me if I'm wrong, there might be something I'm not getting, but wouldn't it make the most sense in most cases just to have a loop that looks like this (in glorious Pseudocode Wink )

speed = 5;
now = some measure of time;
heartbeat =now + speed.

while (game is playing) {
    if (now = heartbeat)
           heartbeat = now + speed;

Wouldn't that work in Quake and in Tetris?