8 min read

In this article by Jorge Jordán, author of the book Cocos2d Game Development Blueprints, we will see how to run the newly created project in Xcode.

(For more resources related to this topic, see here.)

Click on Run at the top-left of the Xcode window and it will run the project in the iOS Simulator, which defaults to an iOS 6.1 iPhone:

Voilà! You’ve just built your first Hello World example with Cocos2d v3, but before going further, let’s take a look at the code to understand how it works.

We will be using iOS Simulator to run the game unless otherwise specified.

Understanding the default project

We are going to take an overview of the classes available in a new project, but don’t worry if you don’t understand everything; the objective of this section is just to get familiar with the look of a Cocos2d game.

If you open the main.m class under the Supporting Files group, you will see:

int main(int argc, char *argv[]) {
   @autoreleasepool {
       int retVal = UIApplicationMain(argc, argv, nil,         @"AppDelegate");
       return retVal;
   }
}

As you can see, the @autorelease block means that ARC is enabled by default on new Cocos2d projects so we don’t have to worry about releasing objects or enabling ARC.

ARC is the acronym for Automatic Reference Counting and it’s a compiler iOS feature to provide automatic memory management of objects. It works by adding code at compile time, ensuring every object lives as long as necessary, but not longer.

On the other hand, the block calls AppDelegate, a class that inherits from CCAppDelegate which implements the UIApplicationDelegate protocol. In other words, the starting point of our game and the place to set up our app is located in AppDelegate, like a typical iOS application.

If you open AppDelegate.m, you will see the following method, which is called when the game has been launched:

-(BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    [self setupCocos2dWithOptions:@{          CCSetupShowDebugStats: @(YES),    }];    return YES; }

Here, the only initial configuration specified is to enable the debug stats, specifying the option CCSetupShowDebugStats: @(YES), that you can see in the previous block of code.

The number on the top indicates the amount of draw calls and the two labels below are the time needed to update the frame and the frame rate respectively.

The maximum frame rate an iOS device can have is 60 and it’s a measure of the smoothness a game can attain: the higher the frame rate, the smoother the game.

You will need to have the top and the bottom values in mind as the number of draw calls and the frame rate will let you know how efficient your game will be.

The next thing to take care of is the startScene method:

-(CCScene *)startScene
{
   // The initial scene will be GameScene
   return [IntroScene scene];
}

This method should be overriden to indicate the first scene we want to display in our game. In this case, it points to IntroScene where the init method looks like the following code:

- (id)init
{
   // Apple recommends assigning self with super's return value
   self = [super init];
   if (!self) {
       return(nil);
     }
   // Create a colored background (Dark Gray)
   CCNodeColor *background = [CCNodeColor nodeWithColor:[CCColor
colorWithRed:0.2f green:0.2f blue:0.2f alpha:1.0f]];    [self addChild:background];    // Hello world    CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello World"
fontName:@"Chalkduster" fontSize:36.0f];    label.positionType = CCPositionTypeNormalized;    label.color = [CCColor redColor];    label.position = ccp(0.5f, 0.5f); // Middle of screen    [self addChild:label];    // Helloworld scene button    CCButton *helloWorldButton = [CCButton buttonWithTitle:@"[
Start ]" fontName:@"Verdana-Bold" fontSize:18.0f];    helloWorldButton.positionType = CCPositionTypeNormalized;    helloWorldButton.position = ccp(0.5f, 0.35f);    [helloWorldButton setTarget:self     selector:@selector(onSpinningClicked:)];    [self addChild:helloWorldButton];    // done    return self; }

This code first calls the initialization method for the superclass IntroScene by sending the [super init] message. Then it creates a gray-colored background with a CCNodeColor class, which is basically a solid color node, but this background won’t be shown until it’s added to the scene, which is exactly what [self addChild:background] does. The red “Hello World” label you can see in the previous screenshot is an instance of the CCLabelTTF class, whose position will be centered on the screen thanks to label.position = ccp(0.5f, 0.5f).

Cocos2d provides the cpp(coord_x, coord_y) method, which is a precompiler macro for CGPointMake and both can be used interchangeably.

The last code block creates CCButton that will call onSpinningClicked once we click on it.

This source code isn’t hard at all, but what will happen when we click on the Start button? Don’t be shy, go back to the iOS Simulator and find out!

If you take a look at the onSpinningClicked method in IntroScene.m, you will understand what happened:

- (void)onSpinningClicked:(id)sender
{
   // start spinning scene with transition
   [[CCDirector sharedDirector] replaceScene:[HelloWorldScene     scene]
       withTransition:[CCTransition
transitionPushWithDirection:CCTransitionDirectionLeft
duration:1.0f]]; }

This code presents the HelloWorldScene scene replacing the current one (InitScene) and it’s being done by pushing HelloWorldScene to the top of the scene stack and using a horizontal scroll transition that will last for 1.0 second. Let’s take a look at the HelloWorldScene.m to understand the behavior we just experienced:

@implementation HelloWorldScene
{
   CCSprite *_sprite;
}
- (id)init
{
   // Apple recommends assigning self with super's return value
   self = [super init];
   if (!self) {
       return(nil);
   }
   // Enable touch handling on scene node
   self.userInteractionEnabled = YES;
   // Create a colored background (Dark Gray)
   CCNodeColor *background = [CCNodeColor nodeWithColor:[CCColor
colorWithRed:0.2f green:0.2f blue:0.2f alpha:1.0f]];    [self addChild:background];    // Add a sprite    _sprite = [CCSprite spriteWithImageNamed:@"Icon-72.png"];    _sprite.position =     ccp(self.contentSize.width/2,self.contentSize.height/2);    [self addChild:_sprite];    // Animate sprite with action    CCActionRotateBy* actionSpin = [CCActionRotateBy
actionWithDuration:1.5f angle:360];    [_sprite runAction:[CCActionRepeatForever
actionWithAction:actionSpin]];    // Create a back button    CCButton *backButton = [CCButton buttonWithTitle:@"[ Menu ]"
fontName:@"Verdana-Bold" fontSize:18.0f];    backButton.positionType = CCPositionTypeNormalized;    backButton.position = ccp(0.85f, 0.95f); // Top Right of
screen    [backButton setTarget:self     selector:@selector(onBackClicked:)];    [self addChild:backButton];    // done    return self; }

This piece of code is very similar to the one we saw in IntroScene.m, which is why we just need to focus on the differences. If you look at the top of the class, you can see how we are declaring a private instance for a CCSprite class, which is also a subclass of CCNode, and its main role is to render 2D images on the screen.

The CCSprite class is one of the most-used classes in Cocos2d game development, as it provides a visual representation and a physical shape to the objects in view.

Then, in the init method, you will see the instruction self.userInteractionEnabled = YES, which is used to enable the current scene to detect and manage touches by implementing the touchBegan method.

The next thing to highlight is how we initialize a CCSprite class using an image, positioning it in the center of the screen. If you read a couple more lines, you will understand why the icon rotates as soon as the scene is loaded. We create a 360-degree rotation action thanks to CCRotateBy that will last for 1.5 seconds. But why is this rotation repeated over and over? This happens thanks to CCActionRepeatForever, which will execute the rotate action as long as the scene is running.

The last piece of code in the init method doesn’t need explanation as it creates a CCButton that will execute onBackClicked once clicked. This method replaces the scene HelloWorldScene with IntroScene in a similar way as we saw before, with only one difference: the transition happens from left to right.

Did you try to touch the screen? Try it and you will understand why touchBegan has the following code:

-(void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
   CGPoint touchLoc = [touch locationInNode:self];
   // Move our sprite to touch location
   CCActionMoveTo *actionMove = [CCActionMoveTo
actionWithDuration:1.0f position:touchLoc];    [_sprite runAction:actionMove]; }

This is one of the methods you need to implement to manage touch. The others are touchMoved, touchEnded, and touchCancelled. When the user begins touching the screen, the sprite will move to the registered coordinates thanks to a commonly used action: CCActionMoveto. This action just needs to know the position that we want to move our sprite to and the duration of the movement.

Now that we have had an overview of the initial project code, it is time to go deeper into some of the classes we have shown. Did you realize that CCNode is the parent class of several classes we have seen? You will understand why if you keep reading.

Summary

In this article, we had our first contact with a Cocos2d project. We executed a new project and took an overview of it, understanding some of the classes that are part of this framework.

Resources for Article:


Further resources on this subject:


LEAVE A REPLY

Please enter your comment!
Please enter your name here