Welcome to my Programming Blog...

I am currently working on a couple of projects: An original game called "Implosion" which I am porting from Flash to the iPad, and a remake of Q*bert in Python (pygame), as part of the class I am teaching. Please feel free to use the "Labels" (at right) to follow a specific project or theme. If you are one of my Python students, I recommend that you check out the Python thread.

Thursday, January 13, 2011

Making a Scene

Here's something we didn't discuss in class.... the CCScene class.

We've said before that CCLayers are like sheets of transparency, which might be made, in turn, of subsheets of transparency. Perhaps the idea behind a CCScene is a box that holds a bunch of transparencies. And although you can see lots of CCLayers at once, you can only see one CCScene at a time.

So changing a scene then, means dramatically changing the look and feel of the game. A classic example of this would be to have one scene for a menu, another scene for your game, itself, and perhaps a third scene for a pause screen.

In fact, you have been making scenes all along! Your program doesn't really start with HelloWorldScene - it starts with the AppDelegate.m class which runs a method called applicationDidFinishLaunching: after all the behind-the-scenes stuff is set up. The very last thing it does is to tell the Director of your game to start running a scene from your HelloWorldScene class.

The next surprise is that your HelloWorldScene file isn't really a Scene - it's a Layer! Don't believe me? Check out the line in HelloWorldScene.h that says: @interface HelloWorld : CCLayer. However there is a function in HelloWorld that is called "+(id)scene:." If you look at the code for this, you can see that its job is to create a new scene, put a single HelloWorld layer into it and return that scene to whomever called the function.

So, if you wanted to create another scene (such as a GameMenuScene), you'd want to copy the default "HelloWorldScene" .h and .m files and modify them to make a GameMenu class. Then you'd change the  last line of the applicationDidFinishLaunching in your program's MyGameTitleAppDelegate.m file so that it read:
[[CCDirector sharedDirector] runWithScene: [GameMenu scene]];

Supposing you had two classes, GameMenu and MainGame, both CCLayers with +(id)scene methods. Then once you had the GameMenu running, if the player pressed a button, the GameMenu class could detect it and change the scene to start the game:
[[CCDirector sharedDirector] replaceScene: [MainGame scene]];
(Note: you should only use "runWithScene" at the start of the program. After that, use "replaceScene.")


Then, in the MainGame class, if you win the game (or lose) you can replace the scene again with the GameMenu.

If you are using several scenes, memory considerations will come more to the fore, so we may need to take some specific steps to avoid running out of memory. But we'll cross that bridge when we come to it.

One thing that I can think of that may prove interesting is a way to transfer information (e.g., a score) between scenes. I have some ideas, so by the time you get to this, let's see whether we can work it out.

1 comment:

  1. Here's an example of the scenes in action. (http://tinyurl.com/4vmovpn)

    There are three scenes here - MenuScene, LandScene and SeaScene. The App Delegate calls up the MenuScene (at the end of it's applicationDidFinishLaunching" function) and then the menu can selectively launch LandScene or SeaScene. They, in turn relaunch the MenuScene.

    There's also some stuff in the Menu Scene's init function for making an easy menu system, without all the trouble of SneakyButtons.

    ReplyDelete