Book Image

Creating Games with cocos2d for iPhone 2

By : Paul Nygard
Book Image

Creating Games with cocos2d for iPhone 2

By: Paul Nygard

Overview of this book

Cocos2d for iPhone is a simple (but powerful) 2D framework that makes it easy to create games for the iPhone. There are thousands of games in the App Store already using cocos2d. Game development has never been this approachable and easy to get started. "Creating Games with cocos2d for iPhone 2" takes you through the entire process of designing and building nine complete games for the iPhone, iPod Touch, or iPad using cocos2d 2.0. The projects start simply and gradually increase in complexity, building on the lessons learned in previous chapters. Good design practices are emphasized throughout. From a simple match game to an endless runner, you will learn how to build a wide variety of game styles. You will learn how to implement animation, actions, create "artificial randomness", use the Box2D physics engine, create tile maps, and even use Bluetooth to play between two devices. "Creating games with cocos2d for iPhone 2" will take your game building skills to the next level.
Table of Contents (16 chapters)
Creating Games with cocos2d for iPhone 2
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Scoring and excitement


The game works well with the development we have covered, but there are a few places where we can add a little more visual flair and some excitement. Players love having a game that keeps score. They also love animation. There is excitement to be had by having the ability to lose. Let's give the player what they want.

We build the score and lives displays using CCLabelTTF labels, with the variables playerScore and livesRemaining as their label contents. These are declared as variables of the layer, so we can easily update them. When we start animating tiles, it will be useful to know where the score and lives displays are on screen.

There are two main approaches to adding text to the screen: CCLabelTTF and CCLabelBMFont . Both have their uses, which we will briefly outline here. CCLabelTTF uses a standard TTF font file. The way it draws the text on the screen is not very efficient and can cause performance issues in some uses. The other approach, CCLabelBMFont, uses a bitmap (image file) of the font and internally uses a batch node to render the text. This means it is highly efficient at drawing, with very little performance concern. Other than the use of a TTF file versus an image file, the way you code for them is very similar. One potential issue with a BMFont file is that you must have the entire font in a single bitmap. If you are using a large font size, this often causes you to need to leave out some characters that may be needed to support international keyboards. A TTF file does not have this problem. Also, it is common with the CCLabelBMFont approach to have multiple versions of the font if you want to use different font sizes. In this book, we will use CCLabelTTF labels throughout because we do not have any performance (frame rate) concerns with any of these projects.

If we were to have performance issues, we would certainly switch to using CCLabelBMFont instead of CCLabelTTF. We leave it as an exercise for the reader to convert these projects to use the CCLabelBMFont class. (For creation of the bitmaps, an excellent resource is Glyph Designer, available at http://glyphdesigner.71squared.com.)

Filename: MTPlayfieldLayer.m

-(CGPoint) scorePosition {
    return ccp(size.width - 10 - tileSize.width/2,
               (size.height/4) * 3);
}

-(CGPoint) livesPosition {
    return ccp(size.width - 10 - tileSize.width/2,
               size.height/4);
}

Rather than hardcoding the values in multiple places, it is a preferred approach to create helper methods such as scorePosition and livesPosition, which return a CGPoint reference of where those elements are onscreen. Here we see the calculations, which place the score and lives near the left edge of the screen, with the score three quarters of the way up the screen, and the lives one quarter of the way up the screen.

The creation of simple labels is very basic, using the positioning we saw above. To see how the score and lives are created, please consult the accompanying code bundle for this book.

Now we will need a way to score and animate the tiles when the player makes a successful match. When a match is scored, we will fly the tiles to the score, and then have them shrink into the score position until they disappear. Let's see how that works:

Filename: MTPlayfieldLayer.m

-(void) scoreThisMemoryTile:(MTMemoryTile*)aTile {
    // We set a baseline speed for the tile movement
    float tileVelocity = 600.0;
    
    // We calculate the time needed to move the tile
    CGPoint moveDifference = ccpSub([self scorePosition],
                                    aTile.position);
    float moveDuration = ccpLength(moveDifference) /
                                    tileVelocity;
    // Define the movement actions
    CCMoveTo *move = [CCMoveTo actionWithDuration:
               moveDuration position:[self scorePosition]];
    CCScaleTo *scale = [CCScaleTo actionWithDuration:0.5
                                            scale:0.001];
    CCDelayTime *delay = [CCDelayTime
                          actionWithDuration:0.5];
    CCCallFuncND *remove = [CCCallFuncND
                    actionWithTarget:self
                    selector:@selector(removeMemoryTile:)
                    data:aTile];

    // Run the actions
    [aTile runAction:[CCSequence actions:move, scale,
                      delay, remove, nil]];
    
    // Play the sound effect
    [[SimpleAudioEngine sharedEngine]
                        playEffect:SND_TILE_SCORE];
    
    // Remove the tile from the tilesInPlay array
    [tilesInPlay removeObject:aTile];
    
    // Add 1 to the player's score
    playerScore++;
    
    // Recalculate the number of lives left
    [self calculateLivesRemaining];
}

Here we leverage the cocos2d actions heavily, using the stock actions of CCMoveTo, CCScaleTo, CCDelayTime, and CCCallFuncND. One aspect of our flying-to-score effect is that we want the tiles to move at a constant rate. If we hardcoded a duration for the CCMoveTo action, the tiles closer to the score would move slowly, and those farther away would move really fast. To achieve a constant rate, we set a desired speed (tileVelocity), then calculate how far away the tile is from the score. We divide these out to arrive at the correct movement duration for this tile. After we initiate the actions, we increment the score by one (playerScore++), and call the calculateLivesRemaining method (which we will see shortly).