Setting Up Cocoa For Games

Sage
Posts: 1,066
Joined: 2004.07
Post: #1
After looking around, I'm getting a lot of the Model, View, Controller Paradigm. I don't quite understand this arrangement. I'm used to C++ where you just have a main.cpp and then other files that get called as needed for classes, structures, and various functions. I have one file for my Physics functions. One for my personal math functions. Then I have about six more for classes and structures. But everything is called/created in the main.cpp. I guess my main confusion is the fact that no tutorial I've seen has actually done anything in the main.m file.

If you know about how I currently set up projects (from the bad description above) can you help me transition into this new way of thinking? Or perhaps a different train of thought for using Cocoa?
Quote this message in a reply
Moderator
Posts: 916
Joined: 2002.10
Post: #2
I use the use a gameview class, which is subclassed from NSOpenGLView class, for controlling everything gui/input related paradigm. And then have any outside classes needed for controlling in game objects or whatever.
Quote this message in a reply
Member
Posts: 269
Joined: 2005.04
Post: #3
Create two classes in X-Code. Just for the hell of it, let's call them GameModel and GameView. GameModel inherits from NSObject and GameView inherits from NSOpenGLView (I'm assuming a 3D game here). Add "IBOutlet GameModel *model;" to GameView's instance variables. In Interface Builder read in both GameView.h and GameModel.h, instantiate GameModel, and add a CustomView to your window. Set the custom class on the view to GameView, then connect the view to your instantiated GameModel.

Back to X-Code. In awakeFromNib for both classes set up an NSTimer. In GameModel, whenever the timer fires the game simulation will be updated. Even without outside interference the simulation will chug along happily simulated whatever game you've created. In GameView, the method called by the timer will grab data from the Model for drawing. So let's say you have a sprite class that contains entity graphics. The GameView will keep an instance for each player/enemy class/whatever that you have in your game. The GameView will ask GameModel the player's position, and then draw the appropriate graphics in the right place.

A controller isn't strictly necessary for a game. I find that they just get in the way usually. In a game, the controller's sole purpose is to handle player input. The GameView can handle that easier than a separate class can. Just make the GameView firstResponder and add keyUp/keyDown/mouseMoved/whatever methods to the view. The view will then pass changes along to the model. Player input should be the only "set" accessing going on with the model. The model simulation shouldn't be modified by outside forces (like the view).

That's a basic overview of how my games are setup. Any questions? Obj-C and MVC are definitely different than procedural or C++-style OOP programming and take a little bit of getting used to. If you do a google search for "Model View Controller" you should get a ton of hits to some pretty good articles. I had to read over a dozen before it really clicked with me.
Quote this message in a reply
Sage
Posts: 1,234
Joined: 2002.10
Post: #4
MVC is about object abstraction, not source code organization.

A good example of MVC is coding an NSTableView. The V is the view; all it knows how to do is redraw cells in rows and columns. The M is the data, all it knows is how to store and retrieve values. The C is the glue tying the two together, usually handling user interaction.

That organization indicates a general way to organize your source code, but it's not the same thing. A lot of MVC-driven stuff in Cocoa is GUI oriented (as far as coding the first half of your app entirely in IB) so what goes in main.cpp is no longer important. It's the view objects you interact with, and the stuff they represent, that you have to think about.
Quote this message in a reply
Sage
Posts: 1,234
Joined: 2002.10
Post: #5
Indeed, controllers are not strictly necessary; especially for simple applications. A lot of the controller glue logic can be replaced by key-value observing in 10.3's IB. But, that's another whole set of tutorials to worry about later.
Quote this message in a reply
Vertizor
Unregistered
 
Post: #6
main.m in Cocoa development only serves as the module entry point (kinda like the _main CRT symbol). In main(), you just launch the message loop and the subsystem takes care of everything else.

You implement the exact behaviors of classes in their implementation files. Your old style of development involved setting up all the relationships between classes and the objects at runtime. This process is as you decribed it, it all happens in main.cpp. But in Cocoa, there's a lot that goes on which you don't see in code. The NIB file is very important for this. Back in the days of ProjectBuilder I remember seeing in the project properties sheet, we could specify what the main NIB file was (in cases where a bundle has more than one NIB file). Furthermore you can specify the resource name of your main window within the NIB file.

I'm sure you're come across the -awakeFromNib: method before. The your main window is created from the resource in the NIB file, all the connections are established. Instances of the child controls are created, it all comes to life in that moment.

Lets say you create a non-GUI, non-visual class. You want it to communicate with another class that is a visual element (for ex. your NSOpenGLView widget). Well you need to create outlets on one or the other class, and make the connection from within IB. You can have bi-directional communications if both classes have an outlet reserved for each other and you connect classA's outlet to classB, and classB's outlet to classA. First you need to click the "Classes" tab, find your custom made class, then create an instance of it (the command is in the menus somewhere, or in a context menu). This will create an icon to represent an instance of that class. When the NIB file is loaded when your app starts, that's the actual instance of the object and its lifetime lasts for the lifetime of the app, or until you manually release it. Open up the Info view for that class and add an outlet. Select that outlet. Holding down CTRL and click on the icon that represents the instances of that class. Drag the blue line to connect it to whatever other object you want to connect the outlet to and press the Connect button. The outlet will have a name, just like a member variable. You use that member variable (outlet) just like in C++.

Code:
// in C++
ClassA object;   // declaration in header file
ClassA* object2;

object.foo();    // using the instance in cpp file
object2 = new ClassA;
object2->foo();


//Objective-C version
IBOutlet object;  // in the header file

[object foo];   // usage in *.m file

You don't always have to use the "IBOutlet" identifier. In fact, in Interface Builder where you create the outlet you can specify the exact class it is to be. Leaving it as IBOutlet will make it a datatype "id" which makes no assumptions as to what the underlying class is, so it can be flexible. But sometimes, in order to get at class specific methods or member variables, you have to specify the class type in IB (which puts it in the header file).

Get into the habit of changing things around in IB, then use the command in IB to write out the source files. It'll put them into your project but if you've made changes to those files yourself, rather than replace them, use the file merging tool. This is the best diff tool I've ever seen.
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #7
I think I'm almost getting this. For some reason when I run my programs, they appear behind some windows and aren't actually running. By this I mean they have no menu at the top and no icon in the dock. What is wrong? I haven't even coded anything. Just did some stuff in IB and ran it.
Quote this message in a reply
Moderator
Posts: 592
Joined: 2002.12
Post: #8
Take a look at my FlipSquare tutorial series over at CreateMacGames.

http://www.createmacgames.org/index.php?...&Itemid=27

It may help you out with some things.
Quote this message in a reply
Moderator
Posts: 335
Joined: 2002.04
Post: #9
Yup, I'll second the flip square tutorial. It's a pretty good Cocoa primer for games. Aaron Hillegrass' Cocoa book is also really good.
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #10
I did take a look at flipsquare again. I also fixed my problem without conciously doing anything so I'm not sure what went wrong. Thanks for the help.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  setting up opengl w/cocoa Leroy 5 4,716 Jun 18, 2007 06:00 PM
Last Post: kelvin
  Carbon or Cocoa for Games Nick 26 13,981 Mar 11, 2005 12:59 PM
Last Post: Duane
  Optimizing Cocoa Games Griggs 6 6,532 May 13, 2002 01:45 PM
Last Post: ChrisD