Cocos2d for iPhone: Surfing Through Scenes

0
85
9 min read

 

Cocos2d for iPhone 0.99 Beginner’s Guide

Cocos2d for iPhone 0.99 Beginner's Guide

Make mind-blowing 2D games for iPhone with this fast, flexible, and easy-to-use framework!

  • A cool guide to learning cocos2d with iPhone to get you into the iPhone game industry quickly
  • Learn all the aspects of cocos2d while building three different games
  • Add a lot of trendy features such as particles and tilemaps to your games to captivate your players
  • Full of illustrations, diagrams, and tips for building iPhone games, with clear step-by-step instructions and practical examples
        Read more about this book      

(For more resources on Cocos2d, see here.)

We’ll be doing a lot of things in this article, so let’s get started.

Aerial Gun, a vertical shooter game

Let’s talk about the game we will be making.

Aerial Gun, as I said earlier, is a vertical shooter game. That means you will be in control of an airship which will move vertically. Actually, the airship won’t be moving anywhere (well except to the left and right); what is really going to move here is the background, giving the sense the airship is the one moving.

The player will be able to control the airship by using accelerometer controls. We’ll also provide some areas where the player can touch to fire bullets or bombs to destroy the enemies.

Enemies will be appearing at different time intervals and will have some different behaviors attached to them. For example, some of them could just move towards the airship, others may stay there and shoot back, and so on. We’ll do it in a way you can create more custom behaviors later.

For this game we will be using the Cocos2d template again, just because it is the easier way to have a project properly set up, at least to begin our work.

So, follow the same steps as when we created the Coloured Stones game. Just open Xcode and go to the File menu, select to create a new project. Then choose the Cocos2d template (the simple one, without any physics engine) and give a name to the project. I will call it AerialGun. Once you do that, your new project should be opened.

Creating new scenes

We will begin this new game by first doing a couple of scenes other than the one that holds the actual game.

If you take a look at the class that the template generates, at first sight you won’t find what would appear to be a scene. That is because the template handles that in a confusing fashion, at least for people who are just getting started with Cocos2d. Let’s take a look at that. Open the newly generated HelloWorldScene.m file.

This is the same code in which we based our first game. This time we will analyze it so you understand what it is doing behind scenes. Take a look at the first method of the implementation of the HelloWorld Layer:

+(id) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];

// 'layer' is an autorelease object.
HelloWorld *layer = [HelloWorld node];

// add layer as a child to scene
[scene addChild: layer];

// return the scene
return scene;
}

If you remember well, this is the method that get’s called in the AppDelegate when the Director needs to start running with a scene. So why are we passing the method of a layer instead of an instance of a CCScene class?

If you pay attention to the +(id)scene method of the layer, what it does is to instantiate a CCScene object, then it instantiates a HelloWorld object (the layer), and then it adds that layer to the scene and returns it.

This actually works as you have witnessed and is pretty quick to set up, and get you up and running. However, sometimes you will need to have you own custom scenes, that is a class that inherits from CCScene and extends it in some fashion.

Now we are going to create some of the scenes that we need for this game and add a layer to each one. Then when it is time to work with the game scene we will modify it to match our needs.

Before doing anything, please change the name of the HelloWorldlayer to GameLayer and the name of the HelloWorldScene to GameScene, just as we did back then with our first game.

Time for action – creating the splash and main menu scene

We will begin with a simple scene, the splash screen. A splash screen is the first thing that appears as you launch a game. Well, the second if you count the Default.png image. The objective of this screen is to show the player some information about the developer, other companies that helped, and so on. Most times you will just show a couple and logos and move to the main menu.

So, what we will do now is put a new Default.png image, then create the SplashScene.

The Default.png image is located in your project’s Resources group folder and it is the first image that is shown when the application is launched. You should always have one, so that something is shown while the application is being launched. This happens before anything is initialized, so you can’t do anything else other than show this image. Its dimensions must be 320 * 480 (when developing for older generation iPhones), so if your game is supposed to be in landscape mode, you should rotate the image with any graphics software before including it in your project.

The SplashScene is going to show a sprite for a moment, then fade it, show another one and then move to the GameScene.

Let’s add a new file to the project. Select New File (CMD + N) from the File menu, then select Objective-C class (we are going to do it from scratch anyways) and name it SplashScene.

This file will hold both the SplashScene and the SplashLayer classes. The SplashLayer will be added as a child of the SplashScene, and inside the layer we will add the sprites.

Before writing any code, add to the project the three splash images I created for you. You can find them in the companion files folder. Once you have them added into your project we can begin working on the SplashScene.

The following is the SplashScene.h:

#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "MainMenuScene.h"

@interface SplashScene : CCScene {

}

@end


@interface SplashLayer : CCLayer {

}

@end

And the SplashScene.m file:

#import "SplashScene.h"

//Here is the implementation of the SplashScene

@implementation SplashScene

- (id) init
{
self = [super init];
if (self != nil)
{

[self addChild:[SplashLayer node]];

}
return self;
}

-(void)dealloc
{
[super dealloc];
}

@end

//And here is the implementation of the SplashLayer


@implementation SplashLayer
- (id) init
{
if ((self = [super init]))
{

isTouchEnabled = YES;

NSMutableArray * splashImages = [[NSMutableArray alloc]init];
for(int i =1;i<=3;i++)
{
CCSprite * splashImage = [CCSprite spriteWithFile:[NSString
stringWithFormat:@"splash%d.png",i]];
[splashImage setPosition:ccp(240,160)];
[self addChild:splashImage];
if(i!=1)
[splashImage setOpacity:0];

[splashImages addObject:splashImage];
}

[self fadeAndShow:splashImages];


}
return self;
}

//Now we add the methods that handle the image switching


-(void)fadeAndShow:(NSMutableArray *)images
{
if([images count]<=1)
{
[images release];
[[CCDirector sharedDirector]replaceScene:[MainMenuScene node]];
}
else
{

CCSprite * actual = (CCSprite *)[images objectAtIndex:0];
[images removeObjectAtIndex:0];

CCSprite * next = (CCSprite *)[images objectAtIndex:0];


[actual runAction:[CCSequence actions:[CCDelayTime actionWithDuration:2],
[CCFadeOut actionWithDuration:1],[CCCallFuncN actionWithTarget:self
selector:@selector(remove:)],nil]];
[next runAction:[CCSequence actions:[CCDelayTime actionWithDuration:2],
[CCFadeIn actionWithDuration:1],[CCDelayTime actionWithDuration:2],
[CCCallFuncND actionWithTarget:self selector:@selector(cFadeAndShow:
data:) data:images],nil]];

}


}

-(void) cFadeAndShow:(id)sender data:(void*)data
{
NSMutableArray * images = (NSMutableArray *)data;
[self fadeAndShow:images];
}

-(void)remove:(CCSprite *)s
{
[s.parent removeChild:s cleanup:YES];
}

-(void)dealloc
{
[super dealloc];
}

@end

As you may notice, I have put together two classes in only one file. You can do this with any number of classes, as long you don’t get lost in such a long file. Generally, you will create a pair of files (the .m and .h) for each class, but as the SplashScene class has very little code, I’d rather put it there.

For this to work properly, we need to make some other changes. First, open the AerialGunAppDelegate.m file and change the line where the the Director starts running the GameScene. We want it to start by running the SplashScene now. So replace that line with the following:

[[CCDirector sharedDirector] runWithScene:[SplashScene node]];

Also remember to import your SplashScene.h file in order for the project to properly compile.

Finally, we have to create the MainMenuScene, which is the scene the Director will run after the last image has faded out. So, let’s create that one and leave it blank for now.

The following is the MainMenuScene.h file:

#import <Foundation/Foundation.h>
#import "cocos2d.h"

@interface MainMenuScene : CCScene {

}

@end


@interface MainMenuLayer : CCLayer {

}

@end

The following is the MainMenuScene.m file:

#import "MainMenuScene.h"


@implementation MainMenuScene

- (id) init
{
self = [super init];
if (self != nil)
{

[self addChild:[MainMenuLayer node]];

}
return self;
}

-(void)dealloc
{
[super dealloc];
}

@end

@implementation MainMenuLayer
- (id) init
{
if ((self = [super init]))
{

isTouchEnabled = YES;

}
return self;
}

-(void)dealloc
{
[super dealloc];
}
@end

That would be all for now. Run the project and you should see the first image appear. Then fade to the next one after a while and continue till the last one. Once the last one has faded out, we move on to the MainMenuScene.

What just happened?

Creating a new scene is as easy as that. You can see from the MainMenuScene code that what we are doing is quite simple; when the MainMenuScene gets created we just instantiate the MainMenuLayer and add it to the scene. That layer is where we will later add all the necessary logic for the main menu.

The MainMenuScene as well as the SplashScene both inherit from the CCScene class. This class is just another CCNode.

Let’s take a little look at the logic behind the SplashScene:

NSMutableArray * splashImages = [[NSMutableArray alloc]init];
for(int i =1;i<=3;i++)
{
CCSprite * splashImage = [CCSprite spriteWithFile:[NSString
stringWithFormat:@"splash%d.png",i]];
[splashImage setPosition:ccp(240,160)];
[self addChild:splashImage];
if(i!=1)
[splashImage setOpacity:0];

[splashImages addObject:splashImage];
}

[self fadeAndShow:splashImages];

This piece of code is from the SplashLayer init method. What we are doing here is creating an array that will hold any amount of sprites (in this case, three of them). Then we create and add those sprites to it. Finally, the fadeAndShow method is called, passing that newly created array to it.

The fadeAndShow method is responsible for fading the images it has. It grabs the first image in the array (after that, the sprite is removed from the array). It then grabs the next one. Then it applies actions to both of them to fade them in and out.

The last action of the second sprite’s action is a CCCallFuncND, which we use to call the fadeAndShow method again with the modified array. This occurs if there is more than one remaining sprite in the array. If there isn’t, the fadeAndShow method calls the Director’s replaceScene method with the MainMenuScene.

I have made the SplashLayer logic, so you can add more splash images to the array (or leave just one) if you like. Generally, just one or two images will be more than enough.

LEAVE A REPLY

Please enter your comment!
Please enter your name here