Vous êtes sur la page 1sur 46

Fr

ee

Cocos2d Cross-Platform Game Development Cookbook Second Edition

The book starts by implementing sprites and animations. You will learn how to add scenes to a game, such
as the Gameplay Scene and the options scene, and create menus and buttons in these scenes as well
as creating transitions and program user interactions such as tapping, holding, and swiping. You'll then
add accelerometer inputs and physics to the scene and make objects respond to the input. You will also
learn how to add dynamic lighting to your game and use industry-wide tools, such as TexturePacker, Glyph
Designer, PhysicsEditor, Particle Designer, and Sprite Illuminator, to create more visually appealing and
performance-optimized games.

What this book will do


for you...
Build custom sprites with custom animations

for the game


Build interactivity into your game by adding

gestures and touch interactions


Understand AI enemy programming and

pathfinding to make games more exciting


Add physics to your game to make it more

lively and interactive


Get familiar with the Swift and SpriteBuilder

implementations along with Objective-C


programming
Perform a hassle-free deployment of

games built in iOS onto Android


the game more colorful

A straightforward and easy-to-follow format


A selection of the most important tasks

and problems

Carefully organized instructions to solve

problems efficiently

Clear explanations of what you did


Solutions that can be applied to solve

real-world problems

$ 49.99 US
31.99 UK

community experience distilled

P U B L I S H I N G

Prices do not include


local sales tax or VAT
where applicable

P U B L I S H I N G

Visit www.PacktPub.com for books, eBooks,


code, downloads, and PacktLib.

Siddharth Shekar

Add effects and particle systems to make

Inside the Cookbook...

Cocos2d Cross-Platform Game Development Cookbook


Second Edition

Cocos2d is the world's leading game development framework for developing iOS games. With the introduction
of Swift and SpriteBuilder, it has become easier to develop the games of your dreams without effort.

Sa

pl
e

Quick answers to common problems

Cocos2d Cross-Platform Game


Development Cookbook
Second Edition
Develop games for iOS and Android using Cocos2d with the aid
of over 70 step-by-step recipes

Siddharth Shekar

In this package, you will find:

The author biography


A preview chapter from the book, Chapter 1 'Sprites and Animations'
A synopsis of the books content
More information on Cocos2d Cross-Platform Game Development
Cookbook Second Edition

About the Author


Siddharth Shekar is a game developer with over 5 years of industry experience in game
development. He has developed several games and published them on the iOS, Android,
Amazon, and Windows Phone App Stores.
Siddharth has been programming for the last 11 years and is adept at C++, C#, Objective-C,
Java, JavaScript, LUA, and now Swift. He has experience in developing games for the web,
mobile, and desktop using Flash, Cocos2d, Cocos2d-x, Unity 3D, and Unreal Engine. Siddharth
has also worked with graphics libraries such as DirectX, OpenGL, and OpenGL ES.
Apart from developing games, he also conducts game development workshops in major
engineering colleges and is a visiting faculty in game development institutes.
Siddharth is also the author of the books Learning Cocos2d-x Game Development and
Learning iOS 8 Game Development Using Swift, both published by Packt Publishing.
Currently, he is a lecturer in the game department of Media Design School, Auckland, New
Zealand, where he teaches graphics programming and PlayStation 4/PS Vita native game
development and mentors final year production students.
In his spare time, Siddharth likes to experiment with the latest game development frameworks
and tools. Apart from being an avid gamer, he is interested in animation, computer graphics,
and music, and is an absolute movie buff.
More information about Media Design School and Siddharth Shekar can be found at www.
mediadesignschool.com.

Preface
Since its inception in 2007, the Apple App Store is still going strong with an average of almost
500 apps added on a daily basis. Out of them, almost 80% of the apps are games. Part of
the reason for this is the amazing eco-system created by Apple to make the operating system
and IDE available free of charge, making it easy to access for the average developer. The
other part is Cocos2d, which is still one of the most widely-used free iOS game-development
frameworks that makes games and app development very convenient.
With SpriteBuilder integrating Cocos2d into it, this makes it even more awesome, as now
it is even easier to develop a simple prototype of a game without any code. Moreover, with
minimum effort the same app or game can be run on a varied number of resolutions.
Furthermore, we can now also port these games to Android without any need to rewrite the
code. Cross-platform iOS game development, which was a dream for so many years, has now
finally become a reality.
As Cocos2d itself has been there since the beginning of the first iOS device, the community
is strong and helpful. There are also great tools that have been developed by third-party
developers that make Cocos2d, an already awesome framework, even more awesome.
This book takes you through the recipes that are required to make any game. The chapters
are laid out in a logical manner so that by following each recipe you will get closer to finishing
and porting your game by the end of this book.
Hope to see your creations in the App Store soon.

What this book covers


Chapter 1, Sprites and Animations, teaches you how to draw sprites in a scene, add colored
sprites, and render 2D shapes using primitives. This chapter will also show you how to
animate sprites, move sprites, add different kinds of actions to a sprite, and also look at the
parallax effect to create a more dynamic scene.

Preface
Chapter 2, Scenes and Menus, will cover how to add scenes to the game, such as a gameplay
scene, how to create buttons and labels in the scene, and how to create transitions between
the scenes using various transition effects.
Chapter 3, Gestures, Touches, and the Accelerometer, will discuss various methods of user
interaction, such as tapping, holding, swiping along with adding accelerometer inputs and
gestures to the scene.
Chapter 4, Physics, will provide examples of how to add physics to the scene and make
objects respond to physics. This chapter will also look at different body types and body
properties, adding sprites to a body, applying force and impulse to a body, detecting collision
responses, and building objects, such as a vehicle, by adding physics bodies together.
Chapter 5, Audio, will show you how to edit audio tracks to create music and sound effects,
add the background music and audio effects to the game, add a pause and resume button to
the game, and add a volume slider to control the volume of audio to the options menu.
Chapter 6, AI and A* Pathfinding, will include ways to add Artificial Intelligence to enemies in
the game. This chapter will also look at creating patrolling, chasing, and projectile shooting
enemies. It will cover a pathfinding to create more advanced AI logic for enemies using grids.
Chapter 7, Data Storage and Retrieval, will teach you how to save and load game progress on
the device using NSUserDefault, create and access files using JSON, Plist, and XML files, for
custom storage and retrieval of data.
Chapter 8, Effects, teaches you to add dynamic lighting to your game, manipulate the position
and color of the light source dynamically using touch controls, and add 2D shadows to the
game created by the light source. You will learn to add effects to the game using the CCEffects
class of Cocos2d to create interesting effects in the game.
Chapter 9, Game Tools, provides insights to using industry standard tools, such as
TexturePacker, Glyph Designer, PhysicsEditor, Particle Designer, and Sprite Illuminator, to
create more visually appealing and performance-optimized games.
Chapter 10, Swift/SpriteBuilder Basics, shows you how to develop games in Apple's latest
programming language, Swift. We will see the differences between Objective-C and Swift
in this chapter. We will also see how to import Objective-C classes into Swift to reduce the
redundancy of code. This chapter will also provide insight into using SpriteBuilder to develop
more robust games.
Chapter 11, Porting to Android, will take a look at how to take your existing game developed
for iOS and port it to Android. We will learn how to install the Android Xcode plugin, prepare
the device for deployment, and finally run the project on an Android device.

Sprites and Animations


The topics covered in this chapter are as follows:

Downloading and installing Cocos2d

The 2D coordinate system

Getting access to MainScene

Adding sprites to scenes

Creating a sprite using RenderTexture

Creating a custom sprite class

Animating sprites

Adding actions to sprites

Drawing glPrimitives

Adding the parallax effect

Introduction
In the first chapter, we will cover some basics of the Cocos2d framework so that everyone is
up to speed on the concepts. We will go through the process of downloading and installing
SpriteBuilder/Cocos2d. Then we will cover the 2D coordinate system that Cocos2d uses.

Sprites and Animations


After going through the basics, we will cover the basic properties of sprites and how they can
be added to a scene. We will take a look at how to add an image to a sprite object. We will
discuss how to create a sprite that is used as placeholder asset to test basic game mechanics
and collision in the prototyping stage of any game. We will then consider how to create basic
shapes using glPrimitives. After this, we will move on to discussing how to move, rotate, scale,
and combine actions on the sprite object using actions. Next, we will look at how to animate a
character using sprite frames. Finally, we will add parallax scrolling to the scene to add more
dynamism to it.

Downloading and installing Cocos2d


To create and run a Cocos2d project, you have to install SpriteBuilder and Xcode. In this
section, we will briefly cover how to do so.

Getting ready
To download and install Cocos2d, go to http://cocos2d.spritebuilder.com/
download.

SpriteBuilder is the official installer of Cocos2d now. To install, click on the Cocos2dSpriteBuilder installer link. This will open the Mac App Store Preview page.
If you would like to download an older version of Cocos2d, you can go through the links in the
archive section of the page and download it from there as well.

Chapter 1
Click on the View in Mac App Store link and then click on Launch Application when
prompted.

Once the App Store opens, click on Install to start the installation process. You will need to
sign in to an account to download the file.

Sprites and Animations


Once installed, it should be in your applications folder. Open up Launchpad and click on the
application to open it.

Once the application starts, you will be asked to join the SpriteBuilder mailing list. Add your
e-mail address and click on Continue or select Sign Up Later.

We will go through how to create a small project using SpriteBuilder later in the book. For now,
we are ready to create a new project to work with. Navigate to File | New Project and select a
location to create the project folder.
You can also select the primary language for coding. As we will use Objective-C, make sure
that it is selected at the bottom.

Chapter 1
Once you have selected the location for the project, in the Save As box at the top, give the
project a name. Remember the name and the location of the project folder as we will need it
to open the project in Xcode.

Next, we need to open the project in Xcode. We will first understand how to code using Xcode
as it is essential to make more complex games. In later chapters, we will consider how to use
SpriteBuilder to simplify our game development process.
You can close the SpriteBuilder project as it is not required anymore.

Sprites and Animations


If you don't have Xcode, you can download it from the Mac App Store.

The installation process is very similar to any other app.

How to do it
Perform the following steps:
1. Once you install Xcode, go the to the project folder in the directory you stored the
project in and double-click on projectname.xcodeproj. Here, I named the project
Sprite, so I will double-click on Sprite.xcodeproj:

Chapter 1
2. Once it is open, you should see the interface as follows:

How it works
Click on the play button in the upper-left corner to run the project.

This will run and show the default project running on the simulator. Congrats! You have
Cocos2d running successfully.
7

Sprites and Animations

The 2D coordinate system


In case of 2D game development, we just have two coordinate systems to worry about. The
first is the screen coordinate system, and the other is the object coordinate system.
In 2D, whenever we place an object on screen, we always think as to how far the object is
from the lower-left part of the screen. This is because the lower-left part of the screen is the
origin and not the center of the screen. That is why if you place a sprite without changing its
position, it will be created in the lower-left part of the screen. The screen origin, or the (0,0)
position, is in the lower-left part of the screen. If you want to place the sprite at the center
of the screen, you need to set the position to half the width and the height of the position
property. As everything is with respect to the lower-left part of the screen, this is called the
screen coordinate system.
The object coordinate system refers to the sprite itself. The center of the sprite is at the
center of the object, unlike the screen, which has its origin in the lower-left part. The center
of the sprite is called the anchor point. When you rotate a sprite, it will rotate about its center
because its origin is at its center. You can change the origin of the sprite by accessing the
anchor point property of the sprite.

Chapter 1

Getting access to MainScene


When you launch the application, the scene created in SpriteBuilder will load up by default.
We will have to make some minor changes to get access to the MainScene file and load this
as default instead.

Getting ready
As of now, both the MainScene.h and MainScene.m files have nothing in them. So, open
them up and add the following code in them.

How to do it
First, open up MainScene.h and add the following highlighted code:
@interface MainScene :CCNode{
CGSizewinSize;
}
+(CCScene*)scene;
@end

Next, in the MainScene.m file, add the following:


#import "MainScene.h
@implementation MainScene
+(CCScene*)scene{
return[[self alloc]init];
}
-(id)init{
if(self = [super init]){

Sprites and Animations


winSize = [[CCDirectorsharedDirector]viewSize];
}
return self;
}
@end

Then, navigate to the AppDelegate.m file, which is in the iOS group under Source/
Platforms, as shown in the following screenshot:

Change the code in the startScene function as highlighted here:


- (CCScene*) startScene
{
//Comment or delete line below as shown
//return [CCBReaderloadAsScene:@"MainScene"];
//add below line instead
return [MainScene scene];
}

Now, we have a complete blank project to work with.

10

Chapter 1
If you build and run the project now, you will see nothing but a black screen. To make
sure that we are actually ready to draw something and that it will get displayed onscreen,
let's add some basic code to change the background color.
Add the following code to the init function of the MainScene.m file:
-(id)init{
if(self = [super init]){
winSize = [[CCDirectorsharedDirector]viewSize];
CGPoint center = CGPointMake(winSize.width/2,
winSize.height/2);
//Background
CCNode* backgroundColorNode = [CCNodeColor
nodeWithColor:[CCColor
colorWithRed:0.0f
green:1.0
blue:0.0]];
[selfaddChild:backgroundColorNode];

}
return self;
}

In the init function, after initializing the super init file, we will first get the screen size of
the current device. Then, we will have a helper CGPoint variable, which is used to calculate
the center of the screen.
Then, we will create a new CCNode and call it backgroundColorNode and call the
CCNodeColor class and the nodeWithColor function. In it, we will pass the red, green, and
blue values. As I wanted a green background, I have the value of green as 1 and the rest are 0.
Then, we will add backgroundColorNode to the scene.

11

Sprites and Animations

How it works
Run the project to see the changes.
You will just see a green screen, which is the node that was just added to the scene. This can
be used if you want to have a plain background, and instead of importing an image into the
project, this is a quick way of having any colored background.

Adding sprites to scenes


To display any image onscreen and manipulate it, you will need to add it to the scene using
the CCSprite class. Unlike a regular image, a sprite has properties such as move, scale,
rotate, and so on, which can be used to manipulate the image.

Getting ready
To add sprites to the scene, we will first import the background image in to our project.
12

Chapter 1

How to do it
Add the following code to the init function right below where we added
backgroundColorNode:
//Basic CCSprite - Background Image
CCSprite* backgroundImage = [CCSpritespriteWithImageNamed:@"Bg.png"];
backgroundImage.position = CGPointMake(winSize.width/2,
winSize.height/2);
[selfaddChild:backgroundImage];

Here, we will take the Bg image and add it as a child to the current scene. From the
Resources folder of the chapter, we will drag the Bg-ipad.png and Bg-ipadhd.png files
into the Resources/Published-iOS folder of the project.

We still have to make a small change in the CCBReader.m file. In the Search
inspector, search for the CCFileUtilsSearchMode text, and in place of
CCFileUtilsSearchModeDirectory, make the text CCFileUtilsSearchModeSuffix.
This will change the searchmode file from the folder to suffix mode.

13

Sprites and Animations

How it works
If you build and run now, you will see an image similar to the following screenshot. This way,
we can display sprites on the scene.

Creating a sprite using RenderTexture


RenderTexture is used to create placeholder sprites that can be used to prototype a game.
So, if you want to test your movement and jump code on a sprite but don't have access to a
sprite, this is a quick and dirty way to create a sprite.

Getting ready
To create the RenderTexture sprite, we will create a new function, and this function will
return a sprite when we provide the size and color of the sprite to be produced.

14

Chapter 1

How to do it
In the MainScene.h file, we will add the following highlighted line right under the scene
function we created earlier:
+(CCScene*)scene;
-(CCSprite *)spriteWithColor:(ccColor4F)bgColor
textureWidth:(float)textureWidth
textureHeight:(float)textureHeight;
@end

This function will return CCSprite and take in the color, width, and height that the sprite
should be of.
In the MainScene.m file, we will add the definition of the preceding function below the init
function, as follows:
-(CCSprite *)spriteWithColor:(ccColor4F)bgColor
textureWidth:(float)textureWidth
textureHeight:(float)textureHeight {

CCRenderTexture *rt =
[CCRenderTexture
renderTextureWithWidth:textureWidth
height:textureHeight];
[rtbeginWithClear:bgColor.r
g:bgColor.g
b:bgColor.b
a:bgColor.a];
[rt end];
return [CCSpritespriteWithTexture:rt.sprite.texture];
}

In the function, we will create a new variable called rt of the CCRenderTexture type, and to
it, we will pass the width and height that is passed to the function.

15

Sprites and Animations


Then, we will clear RenderTexture with the color that is passed in. Then, we will call the end
function on rt.
Next, we will create CCSprite by passing in the texture of the rt sprite. This is then returned
by the function.

How it works
To use the RenderTexture function, we will add the following code right after where we
added the background to the scene:
//rtSprite
CCSprite* rtSprite = [self spriteWithColor:ccc4f(1.0, 1.0, 0.0, 1.0)
textureWidth:150textureHeight:150];
rtSprite.position = CGPointMake(winSize.width/2,
winSize.height/2);
[selfaddChild:rtSprite];

We will create a new variable called rtSprite of the CCSprite type and assign the sprite
that will be created by calling our function to it.
While calling the function, we will create a color of the ccc4f type and pass in the r, g, b, and
a values. For yellow, we will pass 1 for red and green. We will provide a width and height value
of 150 each.
Then, the sprite will be positioned at the center and added to the scene. Run the scene to see
the result.

16

Chapter 1

There's more
The color of the sprite can be changed by changing the rgba color value.
For example, here, I changed the value to (1.0, 0.0, 1.0, 1.0) for yellow, and you can see
the result as follows:
//rtSprite
CCSprite* rtSprite = [self spriteWithColor:ccc4f(1.0, 0.0, 1.0, 1.0)
textureWidth:150textureHeight:150];
rtSprite.position = CGPointMake(winSize.width/2, winSize.height/2);
[selfaddChild:rtSprite];

17

Sprites and Animations

Creating a custom sprite class


We just considered how to add a sprite to a scene; however, in the future, you may want a
separate sprite class so that you can add your own behaviors to the class. In this section, we will
discuss how to create our own custom sprite class by extending the base CCSprite class.

Getting ready
Let's take a look at how to create a custom sprite class so that it can have its own movement
and update the function later.
For this, we will have to create new files.
1. Go to File | New | File. Under iOS | Source, select Cocoa Touch Class. Click on
Next.

2. Next, we will give it a class name. We will select CCSprite as Subclass of and
ObjectiveC as Language. Click on Next.

18

Chapter 1

3. Next, we will click on Create to add the files to your projects.

19

Sprites and Animations

How to do it
Now that the files are created, let's make some changes to them so that it can take a string as
the filename and create the sprite from the file.
In the Hero.h file, we make the following changes:
#import "CCSprite.h"
@interface Hero :CCSprite{
CGSizewinSize;
}
-(id)initWithFilename:(NSString *) filename;
@end

Now, we will change the Hero.m file as follows:


#import "Hero.h"
@implementation Hero
-(id)initWithFilename:(NSString *)filename
{
if (self = [super initWithImageNamed:filename]) {
}
return self;
}
@end

How it works
To create an instance of the newly created custom sprite class, we will go to MainScene.h,
import the Hero.h file, and create a new instance of the Hero type called hero with the
following code:
#import "Hero.h"
@interface MainScene :CCNode{

20

Chapter 1
CGSizewinSize;
Hero* hero;
}

In the MainScene.m file, we will add the following code right after the place we added
rtSprite:
hero = [[Hero alloc]initWithFilename:@"hero.png"];
hero.position = CGPointMake(center.x - winSize.width/4,
winSize.height/2);
[selfaddChild:hero];

Here, we initialized hero with the hero.png file. In the Resources folder, we have to import
the hero-ipad.png and hero-ipadhd.png files into the project in a similar way to how we
added the Bg image files.
We will place hero at one-quarter the width of the screen, to the left of the center of the
screen, and place it at half the height of the screen. Lastly, we will add the hero object to
the scene.

Let's next take a look at how to animate the hero object.

21

Sprites and Animations

Animating sprites
In this section, we will discuss how to animate a sprite. We will change our custom sprite class
to make the character animate. This can be done by providing Cocos2d with a number of
images and asking it to cycle through these images to create the animation.

Getting ready
To animate the sprites, we will add four frames of animation that we will apply to the hero
sprite class and cycle through the images using the repeatForever action. In the next
section, we will cover the actions in detail.

How to do it
In the Resources folder for this chapter, there will be normal, ipad, and ipadhd versions
of the frames for hero. We will import all the files into the project.

22

Chapter 1
In the Hero.m file, we will change the initWithFilename function, as follows:
-(id)initWithFilename:(NSString *)filename
{
if (self = [super initWithImageNamed:filename]) {

NSMutableArray *animFramesArray = [NSMutableArray array];


for (inti=1; i<=4; i++){
[animFramesArrayaddObject:
[CCSpriteFrameframeWithImageNamed:
[NSStringstringWithFormat:@"hero%d.png",i ]]];
}
CCAnimation* animation =
[CCAnimation
animationWithSpriteFrames:animFramesArraydelay:0.3];
CCActionInterval *animate=
[CCActionAnimateactionWithAnimation:animation];
CCAction* repeateAnimation =
[CCActionRepeatForeveractionWithAction:animate];
[selfrunAction:repeateAnimation];
}
return self;
}
@end

First, we will create a new variable called animFramesArray of the NSMutableArray type.
We will then create a for loop starting from index 1 and going to 4, as there are four images.
We will save the frames in the array by passing in the names of the four images that we would
like to loop through.
Next, we create a variable called animation of the CCAnimation type and pass it in the
four frames; also add the delay with which the animation should be played with.

23

Sprites and Animations


We will then create a variable called animate of the CCActionInterval type to create
a loop through the animation. Then, in the next step, we will create CCAction and call the
repeat forever action, which will loop through the animation forever.
Finally, we will run the action on the current class.

How it works
Now, you should be able to see the character blinking. The speed with which the animation is
played is controlled by the delay in the CCAnimation class.

We will see that without making any changes to the instance in MainScene, the custom sprite
animates the character.

24

Chapter 1

Adding actions to sprites


We already saw Actions in action while animating and repeating the player animation.
However, there are a lot more additional actions that you can perform. Further, you can play
these actions together in a sequence.

Getting started
Let's first take a look at a simple action in which we will move the hero along the x axis by half
the width of the screen, and move it down by one-quarter the height of the screen from the
center in the y direction.

How to do it
After we have added the hero to MainScene, we will add the following code:
CGPointfinalPos = CGPointMake(center.x + winSize.width/4, center.y winSize.height/4);
CCActionFiniteTime* actionMove = [CCActionMoveToactionWithDuration
:1.0position:finalPos];
[herorunAction:actionMove];

For convenience, I created a CGPoint called finalPos and stored the final position in it.
Then, I created a variable called actionMove of the CCFiniteAction type, called the
CCMoveTo function, gave it a duration of 1.0 seconds, and specified the position that I
wanted to move the hero to. Finally, I called the runAction function on hero and passed
in the action.

25

Sprites and Animations

How it works
When you run the project, the hero will be to the left of the yellow render sprite and will slowly
start moving towards the lower-right corner if the render sprite is over a period of 1 second.
After 1 second, when the destination location is reached, the action will stop, and the hero will
be stationary again.

There's more
Let's next create a more elaborate action and add a whole bunch of actions in a sequence
and play them one after the other. Therefore, we will remove the previous code and add the
following code instead:
//Actions
CGPointinitPos = hero.position;
CGPointfinalPos = CGPointMake(center.x + winSize.width/4, center.y winSize.height/4);
CCActionFiniteTime* actionMove = [CCActionMoveToactionWithDuration:
1.0position:finalPos];
CCAction *rotateBy = [CCActionRotateByactionWithDuration:2.0 angle:
180];

26

Chapter 1
CCAction *tintTo= [CCActionTintToactionWithDuration:1.0
color:[CCColorcolorWithRed:0.0fgreen:1.0blue:0.0]];
CCAction *delay = [CCActionDelayactionWithDuration:1.0];
CCAction *moveToInit = [CCActionMoveToactionWithDuration:
1.0position:initPos];
CCAction *rotateBack = [CCActionRotateByactionWithDuration:2.0 angle:
180];
CCAction *tintBlue= [CCActionTintToactionWithDuration:1.0
color:[CCColorcolorWithRed:0.0fgreen:0.0blue:1.0]];
CCAction *sequence = [CCActionSequenceactions:actionMove,
rotateBy,tintTo, moveToInit, delay, rotateBack, tintBlue, nil];
[herorunAction:sequence];

Here, as I stored the final position in a variable, I will also store the initial position in a
CGPoint variable called initPos, which we will use later.
The first action is the same moveTo action with which we will move the player.
Next, we will use the rotateBy action; here, we will give the duration and angle in degrees by
which the object should be rotated.
After this, we will use the tintTo action, which will change the color of the object. Once
again, we will give it the duration and color to which we want to the object to change. Here, we
will change the color to green.
We will then call the delay action, which is used to perform an action after a delay. We will
create a delay of 1 second.
Then, we will move the object back to its initial position, change the object color to blue, and
rotate the object again by another 180 degrees.
We will create the CCSequence action and pass in all the actions in the order we want them
to be played; at the end, we will add nil to say that is the end of the list.
At the end, we will call run the sequence action on hero.
Now, the hero will start at the initial position, but when he gets back, he will be blue in color.

27

Sprites and Animations


The output of the code is as follows:

Drawing glPrimitives
Cocos2d uses openGLES, which is a graphics library that enables objects to be displayed
onscreen. In fact, all the drawing that we have done until now uses this library. Cocos2d also
gives you basic access to glPrimitives, which can be used to create basic shapes, such as
circles, squares, rectangles, and so on.

Getting ready
Let's take a look at a few of the examples now. We will begin by creating a simple circle.

28

Chapter 1

How to do it
Right after adding the hero node, we will add the following code:
//drawDotNode
CCDrawNode* dotNode = [CCDrawNode node];
CCColor* red = [CCColorcolorWithRed:1.0fgreen:0.0fblue:0.0f];
[dotNodedrawDot:CGPointMake(winSize.width/2, winSize.height/2) radius:
10.0fcolor:red];
[selfaddChild:dotNode];

glPrimitives are created using the CCDrawNode class. Here, we will create a new instance of
CCDrawNode and call it DotNode. We will create a new CCColor variable called red and
assign the RGBA value of red.
We will then call the drawDot function on CCDrawNode and pass in the location where we
would like to create the circle. We will also pass in the radius and color. In the end, we will add
dotNode to the scene.

How it works
When you run the project, you will see a red dot at the center of the screen.
Here, as we provided the center of the circle and radius, Cocos2d creates the circle and paints
the area inside this region with the color that you specified.
The circle is one example; there are other shapes that can also be created this way.

29

Sprites and Animations

There's more
Next, we will take a look at how to create polygons of any shape with the drawWithPolyVert
function of the CCDrawNode class. Add the following code and replace or comment the
DrawDot node:
// DrawSquareNode
CCDrawNode *squareNode = [CCDrawNode node];
CGPointsquareVerts[4] =
{
CGPointMake(center.x - 50, center.y - 50),
CGPointMake(center.x - 50, center.y + 50),
CGPointMake(center.x + 50, center.y + 50),
CGPointMake(center.x + 50, center.y - 50)
};
CCColor* green = [CCColorcolorWithRed:0.0fgreen:1.0fblue:0.0f];
[squareNodedrawPolyWithVerts:squareVerts
count:4
fillColor:red
borderWidth:1
borderColor:green];
[selfaddChild:squareNode];

We will create a new node of the CCDrawNode type. Next, we will create an array of CGPoint
by calling in squareVerts, which will take in the location of the vertices of the square. We will
then create a new CCColor called green and assign it a green color using the RGBA value.
Then, we will call drawPolyLineWithVerts, pass in the vertices array, give the number
of vertices to draw, pass in the fill color as red, and assign a border width of 1. In the end,
we will pass in the border color as green, which we specified earlier.

30

Chapter 1
Then, we will add squareNode to the scene.
We can simply run the project to see the final result.

We can also make a triangle with the same code. Instead of drawing four nodes, if we just ask
the function to draw three nodes, a triangle will be drawn instead of a square.
We can change the code as follows, in which we will change the count to 3 instead of 4. There
is no need to change the verts array:
CCColor* green = [CCColorcolorWithRed:0.0fgreen:1.0fblue:0.0f];
[squareNodedrawPolyWithVerts:squareVerts
count: 3
fillColor:red
borderWidth:1
borderColor:green];
[selfaddChild:squareNode];

31

Sprites and Animations


We will then run again to see the change:

Using the CCDrawNode class, we can also create line segments between two points.
For this, we will add the following code right after adding the polyline code:
//segment node
CCColor* blue = [CCColorcolorWithRed:0.0fgreen:0.0fblue:1.0f];
CCDrawNode* segmentNode = [CCDrawNode node];
[segmentNodedrawSegmentFrom:center
to:CGPointMake(center.x + 40, center.y + 40)
radius: 2.0
color: blue];
[selfaddChild:segmentNode];

32

Chapter 1
We will define a new CCColor called blue so that we can color the line blue. Next, we will
create a new CCDrawNode class and call it segmentNode.
On segmentNode, we will call the drawSegment function and provide the center of the
screen as the start point and the second point is 40 units in the x direction and 40 units in
the y direction from the center. We will then pass in the radius, which is the thickness of the
line, and the color blue.
The node is then added to the scene.
Note that in the following screenshot, I changed the polyline to draw a square instead of a
triangle:

33

Sprites and Animations

Adding the parallax effect


In this section, we will add a parallax or scrolling background. This is a very popular effect in
games, in which the objects in the foreground move faster as compared to the objects in the
background that move much slower, giving the illusion of depth and motion.

Getting ready
Recall the movies of yesteryear in which the hero or subject remains stationary and acts as if
they are galloping on a horse, and the background is looped to give the illusion that the hero
is actually moving forward in the scene.

34

Chapter 1
We will implement a very simple parallax effect in which all the objects in the background,
such as the trees, bushes, and grass, move at the same speed. So, we will just take the
background image and make it move in a loop.
The parallax effect will be achieved thus: instead of a single sprite of the background image,
we will use two sprites and place them adjacent to each other horizontally at the start of the
game, as seen in the first preceding image. The first sprite will be visible, but the second
sprite will be offscreen and won't be visible to the player initially.
When the game starts, both the sprites will be moved with a certain speed in the negative x
directionthat is toward the left of the screen. Both the sprites will move at the same speed.
So, once the game starts, sprite 1 will slowly go offscreen bit by bit, and the second sprite will
start to get visible.
Once the first sprite goes completely offscreen, it is quickly moved to the end of the second
sprite, which is at the same position that the second sprite was at the start of the game.
Thus, the process continues in a loop. Both the sprites always move toward the left of the
screen. After each sprite goes off screen on the left-hand side, it is placed off screen on the
right-hand side of the screen, and it continues to move left.
There are a couple of things that need to be kept in mind while creating assets for parallax
scrolling and coding a parallax effect. The first is that when creating assets for a parallax
effect, the art needs to be continuous. This means, for example, if you look at the second
image in the preceding section, you will see that the mountains look like a continuous
mountain range. Even though Sprite1 and Sprite2 are two different images, when put
together, they appear as one single image. This can again be seen in the light green bush
below the mountain. The left-hand part of the bush is in Sprite1, and the right-hand part is
in Sprite2, yet when the two sprites are kept adjacent to each other, they give a seamless
illusion of being part of a single bush.
The second aspect to keep in mind is image gap. Even if you make the images seamless and
make the sprites move at the same speed, sometimes you might encounter gaps between the
sprites. This is not a very common problem, but in some frameworks, this problem might exist.
So, to counter this, you can either stretch the images just by a bit so that the sprites overlap
each other and it is not very obvious to the player. The other method is to make sure that
you manually place the sprites at the end of the onscreen sprite and also make necessary
adjustments if required to bridge the gap between the sprites.
This is the main theory behind parallax scrolling. Let's take a look at it in practice in code in
the next section.

35

Sprites and Animations

How to do it
In a similar way to how we created the Hero class, we will create a file of the
CocosTouchClass type and name it ParallaxSprite.
Open the ParallaxSprite.h file and add the following code:
#import "CCSprite.h"
@interface ParallaxSprite :CCSprite{
CGSize _winSize;
CGPoint _center;
CCSprite *_sprite1, *_sprite2;
float _speed;
}

-(id)initWithFilename:(NSString *)filename Speed:(float)speed;


-(void)update:(CCTime)delta;
@end

We will create a few variables that we will use later, such as _winSize and _center,
which will get the size of the screen resolution of the device that the game is running on and
calculate the center of the screen.
We will create two sprite variables to hold the two images which will be cycled during the
parallax effect.
We will also add a _speed variable. This is the speed with which we will move and loop the
images.
In a similar way to the Hero class, we will create an initWithFilename function that will
initiate the class with the filename provided. Additionally, we will also take a float, which will
be the speed of the sprite.
We will also need an update function that will be called 60 times in a second and will update
the position of the two sprites in the class.
This is all for the ParallaxSprite.h file. We will now move on to the ParallaxSprite.m
file.

36

Chapter 1
In the file, we will add the following code:
#import "ParallaxSprite.h"
@implementation ParallaxSprite
-(id)initWithFilename:(NSString *)filename Speed:(float)speed;{
if(self = [super init]){
NSLog(@"[parallaxSprite] (init) ");
_winSize = [[CCDirectorsharedDirector]viewSize];
_center = CGPointMake(_winSize.width/2, _winSize.height/2);
_speed = speed;
_sprite1 = [CCSpritespriteWithImageNamed:filename];
_sprite1.position = _center;
[selfaddChild:_sprite1];
_sprite2 = [CCSpritespriteWithImageNamed:filename];
_sprite2.position = CGPointMake(_sprite1.position.x + _winSize.
width
, _center.y);
[selfaddChild:_sprite2];
}
return self;
}

We will first add the initWithFilename function. In this, we will initialize the super class
and get _winSize.
Next, we will calculate the center of the screen by dividing the width and height by two.
The speed value is assigned to the _speed variable classes.
We will then create the _sprite1 and _sprite2 variables. In spriteWithImageNames,
we will pass the filename variable that will hold the string of the filename.
Note that _sprite1 is placed at the center of the screen, and _sprite2 is placed off screen
by the width of the screen, but at the same height as _sprite1.

37

Sprites and Animations


Both the sprites are then added to the class.
Next, we will add the update function, as follows:
-(void)update:(CCTime)delta{
floatxPos1 = _sprite1.position.x - _speed;
floatxPos2 = _sprite2.position.x - _speed;
_sprite1.position = CGPointMake(xPos1, _sprite1.position.y);
_sprite2.position = CGPointMake(xPos2, _sprite1.position.y);
if(xPos1 + _winSize.width/2 <= 0){
_sprite1.position = CGPointMake(_sprite2.position.x +
_winSize.width, _center.y);
}else if(xPos2 + _winSize.width/2 <= 0){
_sprite2.position = CGPointMake(_sprite1.position.x + _winSize.
width
, _center.y);
}
}

@end

Here, we will calculate the new positions of the individual sprites in the x axis by getting the
current x position of the sprites and then subtracting the speed. We will subtract because we
want the sprites to move in the negative x direction in each update call.
In the next step, we will assign the x position calculated on both the sprites. We will use the
same y position as the value does not change in the y direction.
Next, we will check whether the right-hand edge of the image is visible to the player any more
and has gone beyond the left-hand side of the screen. If this is the case, we will place the
sprite at the offscreen position, the width of the screen from the center of the other sprite, so
that there are no gaps between the sprites.
We will use an "if else" statement here as only one sprite will go beyond the bounds on the
left-hand side of the screen.

38

Chapter 1

How it works
Let's take a look at how to implement this class now. In the MainScene.h class, we will
import the ParallaxSprite.h file and create a new variable called pSprite of the
ParallaxSprite type, as follows:
#import "Hero.h"
#import "ParallaxSprite.h"
@interface MainScene :CCNode{
CGSizewinSize;
Hero* hero;
ParallaxSprite* pSprite;
}

Next, in the MainScene.m file, we will remove the code that was used to add the background
sprite at the start of the chapter and replace it with the following code:
//Basic CCSprite - Background Image - REMOVE
//CCSprite* backgroundImage = [CCSpritespriteWithImageNamed:@"Bg.
png"];
//backgroundImage.position = CGPointMake(winSize.width/2,
winSize.height/2);
//[self addChild:backgroundImage];
//Parallax Background Sprite - ADD
pSprite = [[ParallaxSpritealloc]initWithFilename:@"Bg.png" Speed:5];
[selfaddChild:pSprite];

Here, we will assign the same Bg.png file as we did earlier; however, additionally, we will also
provide a speed value of 5.
Note that we will not call the update function of the ParallaxSprite class as it is called
automatically every frame. Further, you also don't have to schedule it as you did previously
because the function is initialized automatically at the start.

39

Sprites and Animations


And that is all! You can enjoy the parallax sprite effect now.

40

Get more information Cocos2d Cross-Platform Game Development Cookbook


Second Edition

Where to buy this book


You can buy Cocos2d Cross-Platform Game Development Cookbook Second Edition
from the Packt Publishing website.
Alternatively, you can buy the book from Amazon, BN.com, Computer Manuals and most internet
book retailers.
Click here for ordering and shipping details.

www.PacktPub.com

Stay Connected:

Vous aimerez peut-être aussi