oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Building a Game Engine with Cocoa

by Matthew Russell

Classic board games like Checkers are hard to beat, but after so many holiday seasons and family get-togethers, variety becomes essential. Lines of Action (LOA) is a game slightly off the beaten path that you can play with an ordinary Checkers set the next time you decide to dust it off--but in the meantime, let's fire up Xcode and build a small game engine for playing board games like Checkers and LOA using some artificial intelligence.

In this episode, we'll put together a generic, minimalist framework for setting up the board and moving the pieces around using standard Cocoa drawing techniques. Next time, we'll finish off by writing a valid move generator for LOA, although you could really define one for any board game you can imagine. We'll also develop a computer opponent that you can customize with your own heuristics using an artificial intelligence technique called a game tree search.

Build the Skeleton

Like any other Cocoa project, you'll need to have a copy of Apple's developer tools installed on your Mac to follow along and run the sample project. Likewise, there are already a lot of great introductory tutorials here on Mac DevCenter about graphics and Cocoa 101, so take a few moments to brush up if it's been a while. We won't be doing anything all that advanced, but a basic working knowledge of Cocoa and Xcode is assumed from here on out.

First, fire up Xcode and use the assistant to start a new Cocoa application called "Board Game." We'll be adding two new classes right away: an application controller and a subclass of NSView that'll be our gameboard. Using the "File" menu, create a new Objective-C class entitled "AppController" for the former, and another Objective-C class called "GameBoard" for the latter. Under the "Groups & Files" pane in Xcode, drag the resulting four files that are created under the "Classes" folder. In the GameBoard header file, change the line that contains GameBoard : NSObject to be GameBoard : NSView instead, so that GameBoard inherits from NSView instead of NSObject.

Now, expand the NIB Files folder on the same part of the screen to reveal MainMenu.nib, and double-click it to open Interface Builder. In Interface Builder, drag the AppController.h file from Xcode onto the small window that's titled "MainMenu.nib (English)," and you should see AppController appear as a subclass of NSObject under the "Classes" tab. Making sure that "AppController" is selected from the browser view, choose "Instantiate AppController" from Interface Builder's "Classes" menu up on the top of the screen (Figure 1). With your controller instantiated, drag your GameBoard.h file onto the same window, but do not attempt to instantiate it.

Instantiate AppController
Figure 1. Instantiate AppController from the Classes menu in Interface Builder.

Next, drag a "CustomView" from the "Cocoa Container Views" tab of Interface Builder's "Cocoa-Containers" palette onto the big empty window titled "Window." Select the CustomView and press Cmd-3 to load the view's inspector so that you can set the size attributes. Make the width and height of the view equal so that the window will be square, and then set both of the inner springs in the "AutoSizing" box. With the CustomClass now square, resize the window itself so that there is a uniform margin around the view. Finally, select the CustomView, press Cmd-5 to bring up the inspector's section that allows you to qualify your custom class, and choose GameBoard. (GameBoard appears as an option because you dragged your header file onto Interface Builder's main window a few steps ago.) See Figure 2.

Set CustomView Settings Qualify Custom View
Figure 2. Customize the settings for the GameBoard and designate the CustomView as GameBoard in Interface Builder.

There are only two more steps before we finish in Interface Builder. First, click on the window itself and press Cmd-3 to reveal its size inspector, where you can specify a minimum width and height. Choosing 220x220 is a reasonable setting. Next, Ctrl-click on the "Window" icon in the main NIB file under the "Instances" tab, and drag it onto your GameBoard custom view. From the dialog that appears, set the GameBoard to be the window's "initialFirstResponder" (see Figure 3). After completing this step, you can close Interface Builder and head back into Xcode.

Set First Responder
Figure 3. Set the Window's initial first responder to be the GameBoard.

At this point, go ahead and try to "Build and Go" by clicking on the prominent hammer icon in the toolbar. Your project should produce a blank window that does absolutely nothing. But what about the custom view you dragged in? Shouldn't it at least show up? Not unless you have a method in GameBoard that specifies how it should draw itself. The particular method that a view uses to draw itself is called drawRect:. For now, substitute this placeholder version of that method into your GameBoard.m file:

@implementation GameBoard
- (void) drawRect: (NSRect) rect {
    NSRect bounds = [self bounds];
    [[NSColor whiteColor] set];
    [NSBezierPath fillRect: bounds];

If you run your project again, you should now see a plain white canvas staring at you. So far, so good. We'll come back to drawRect: in just a bit.

Pages: 1, 2, 3

Next Pagearrow