Game Loops in Cocoa again

Apprentice
Posts: 14
Joined: 2007.04
Post: #1
Hello everyone, I'm trying to set up a game loop (or event loop) in cocoa but my background in C++ doesn't seem to be usefull. My goal is to write an iphone game but right now I'm working on my Mac since my trusty G4 isn't supported by the iphone SDK. I'm not trying to do anything fancy yet, I'm just trying to implement a grid based collision detection. The problem is the cocoa way of doing things.

My immediate goal is to have a graphic grid and an object that changes the color of the cell that contains it. Each cell is an object with it's own array of objects and the collision detection will happen amongst the objects on the array. The main object might be in up to 4 of these cells.

Back on Xcode I have no idea of where to initialize the game nor where to put the game loop. I plan to do the drawing in a custom NSView and since the NSView subclass will be the first object to be created I was thinking to create the game object in the initWithFrame method and put the drawing code in the drawRect method but I'm not sure if that is the right way to do it.

I searched the Idevgames forums and I found a similar old post (2004) and some guy suggested something like this:

Code:
//---------------------------------------------------------------------------
- (void)myGameInit
{
    NSTimer *timer = [[NSTimer scheduledTimerWithTimeInterval:0.001f
            target:self
            selector:@selector( myGameLoop )
            userInfo:nil
            repeats:YES]
            retain];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSModalPanelRunLoopMode];
}

// this gets called repeatedly by the system automatically
//---------------------------------------------------------------------------
- (void)myGameLoop
{
    // do game stuff here
}

but I'm not sure of where to use it, maybe in the NSView subclass?

I used to use a game object in C++ with a game loop method with a traditional while() and all the input and drawing happened in this loop. I wanted to ask you guys the right way to implement this in cocoa and Xcode.

I have some experience with Xcode and Cocoa but for windowed apps and basically static behavior.
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #2
LOL, I think that was one of my old posts. That was back when I liked using those divider lines. My how times change...

Anyway, that snippet is for use with OpenGL. Basically you subclass an NSView for use with an OpenGL context, then set up a timer to call your drawing method on a regular basis (about 60 Hz when locked to the display refresh of an LCD), to replace the old-school canonical game loop. Setting up the environment ("windowing" as we sometimes refer to it) in Cocoa can become a bit involved with a bunch of gotchas, but it isn't too terrible. Seems like most folks prefer to use SDL for windowing nowadays though.

Personally, since you mention you are familiar with C++ already, I'd just skip the whole Cocoa thing and focus on learning OpenGL, using GLUT first instead. Even on iPhone you won't need very much Cocoa to get the windowing set up and take input.

Quote:I plan to do the drawing in a custom NSView and since the NSView subclass will be the first object to be created I was thinking to create the game object in the initWithFrame method and put the drawing code in the drawRect method but I'm not sure if that is the right way to do it.

That is correct, BTW.
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #3
Here's a more recent post where we were talking about this using Cocoa.
Quote this message in a reply
Apprentice
Posts: 14
Joined: 2007.04
Post: #4
Thanks for your answer Jake, the way that the guy does it is how I have done it, but actually I want to do it in Cocoa/Objective-C. I have been dodging Objective-C for a while since most of the work was for my university and I had to deliver it in a way that could be compiled for Windows. I actually have a brand new OpenGL Bible book but I don't want to get into OpenGL just yet because it will complicate things.

Will your code work with Quartz (2D)? if so, do I need to separate the drawing code from the gameLoop method and put it in drawRect? or is there a way to invoke the drawing from outside drawRect.
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #5
Yes, you should be able to do the timer thing using Quartz too.

To invoke drawRect, the best thing to do is call NSView's display method, like [self display]; That will give you the best synchronization with the window system (AFAIK). You'd do something like this (pseudocode-ish):

Code:
- (id)initWithFrame:(NSRect)frameRect
{
    NSTimer *renderTimer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:0.0]
                                        interval:1.0 / 60.0
                                        target:self
                                        selector:@selector(renderTimerCallback:)
                                        userInfo:nil
                                        repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:renderTimer forMode:NSEventTrackingRunLoopMode];
    [[NSRunLoop currentRunLoop] addTimer:renderTimer forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] addTimer:renderTimer forMode:NSModalPanelRunLoopMode];
    [renderTimer release];
}

- (void)renderTimerCallback:(NSTimer*)theTimer
{
    [self display]; // <-- invokes drawRect
}

- (void)drawRect:(NSRect)rect
{
    // update and draw
}

Note that there is only so much performance you'll get out of Quartz, which is why we usually recommend skipping Quartz and going straight for OpenGL.

You can separate your update from your drawing code right there in drawRect.
Quote this message in a reply
Apprentice
Posts: 14
Joined: 2007.04
Post: #6
Thanks again Jake. Yeah I know that Quartz is slow but right now I just want to focus on my grid collision detection, you know... baby steps, I still don't feel comfortable enough with ObjC and Cocoa for this kind work.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Question about Update() loops anthony 7 3,495 Jun 10, 2007 01:06 AM
Last Post: anthony
  Game Loops in Cocoa Nick 14 6,387 Oct 9, 2004 09:33 PM
Last Post: nabobnick