Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this a good way to do a game loop for an iPhone game?

I'm new to iPhone dev, but trying to build a 2D game. I was following a book, but the game loop it created basically said:

function gameLoop
    update()
    render()
    sleep(1/30th second)
    gameLoop

The reasoning was that this would run at 30fps. However, this seemed a little mental, because if my frame took 1/30th second, then it would run at 15fps (since it'll spend as much time sleeping as updating).

So, I did some digging and found the CADisplayLink class which would sync calls to my gameLoop function to the refresh rate (or a fraction of it). I can't find many samples of it, so I'm posting here for a code review :-) It seems to work as expected, and it includes passing the elapsed (frame) time into the Update method so my logic can be framerate-independant (however I can't actually find in the docs what CADisplayLink would do if my frame took more than its allowed time to run - I'm hoping it just does its best to catch up, and doesn't crash!).

//
//  GameAppDelegate.m
//
//  Created by Danny Tuppeny on 10/03/2010.
//  Copyright Danny Tuppeny 2010. All rights reserved.
//

#import "GameAppDelegate.h"
#import "GameViewController.h"
#import "GameStates/gsSplash.h"

@implementation GameAppDelegate

@synthesize window;
@synthesize viewController;

- (void) applicationDidFinishLaunching:(UIApplication *)application
{
 // Create an instance of the first GameState (Splash Screen)
 [self doStateChange:[gsSplash class]];

 // Set up the game loop
 displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(gameLoop)];
 [displayLink setFrameInterval:2];
 [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

- (void) gameLoop
{
 // Calculate how long has passed since the previous frame
 CFTimeInterval currentFrameTime = [displayLink timestamp];
 CFTimeInterval elapsed = 0;

 // For the first frame, we want to pass 0 (since we haven't elapsed any time), so only
 // calculate this in the case where we're not the first frame
 if (lastFrameTime != 0)
 {
  elapsed = currentFrameTime - lastFrameTime;
 }

 // Keep track of this frames time (so we can calculate this next time)
 lastFrameTime = currentFrameTime;

 NSLog([NSString stringWithFormat:@"%f", elapsed]);

 // Call update, passing the elapsed time in
 [((GameState*)viewController.view) Update:elapsed];
}

- (void) doStateChange:(Class)state
{
 // Remove the previous GameState
 if (viewController.view != nil)
 {
  [viewController.view removeFromSuperview];
  [viewController.view release];
 }

 // Create the new GameState
 viewController.view = [[state alloc] initWithFrame:CGRectMake(0, 0, IPHONE_WIDTH, IPHONE_HEIGHT) andManager:self];

 // Now set as visible
 [window addSubview:viewController.view];
 [window makeKeyAndVisible];
}

- (void) dealloc
{
 [viewController release];
    [window release];
    [super dealloc];
}

@end

Any feedback would be appreciated :-)

PS. Bonus points if you can tell me why all the books use "viewController.view" but for everything else seem to use "[object name]" format. Why not [viewController view]?

like image 895
Danny Tuppeny Avatar asked Mar 11 '10 19:03

Danny Tuppeny


People also ask

Does GameLoop work for iPhone?

Having linked up and created an account, GameLoop will automatically detect the games installed on your iPhone or iPad and add them to your gaming library. If you play games on other platforms, you can also add most of those to your library as well by linking Xbox Live, Playstation Network, and Steam accounts.

What is the point of a game loop?

The game loop is the overall flow control for the entire game program. It's a loop because the game keeps doing a series of actions over and over again until the user quits. Each iteration of the game loop is known as a frame.

Is a game loop an infinite loop?

The game loop itself is a controlled infinite loop that makes your game keep running; it's the place where all your little pieces will be updated and drawn on the screen.

What are the three stages of running the game loop?

The three main processes that occur in the game loop are input, update, and render.


1 Answers

You have Cocos2D listed as a tag in your question but you're not actually using any Cocos2D code. Have you considered doing a Cocos2D implementation for your games? It will save you some unneeded hassle.

As for your syntax question [myObject view] is used for calling methods on myObject while myObject.view is used for setting/getting instance variables exposed as properties. I don't recall if you can retrieve instance variables using [myObject view] as well but if that works then I guess the only difference between the two is the syntax and you could use both methods to retrieve instance variables.

Hope some of that rambling is useful to you.

like image 89
Rob Segal Avatar answered Oct 09 '22 01:10

Rob Segal