Cocos2D-X Tile Map Tutorial: Part 2

Part 2 of a Cocos2D-X tile map tutorial series about his ninja and his quest for watermelon. By Jorge Jordán.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 2 of this article. Click here to view the first page.

Creating a Score Counter

Your ninja is happy and fed, but as player you’d like to know how many melons he’s eaten. You know, you don’t want him getting fat on you.

Usually you’d just add a label to your layer and be done with it. But wait a minute – you’re moving the entire layer all the time, that will screw you up, oh noes!

This is a good opportunity to show how to use multiple layers in a scene – this is the type of situation they are built for. You’ll keep your HelloWorld layer as you’ve been doing, but you’ll make an additional layer called HudLayer to display your label. (Hud means heads up display).

Of course, your two layers need some method of communicating – the HudLayer layer will want to know when the ninja snacks on a melon. There are many ways of getting the two layers to communicate, but you’ll go with the most simple way possible – you’ll hand the HelloWorld layer a pointer to the HudLayer layer, and it can call a method to notify it when the ninja snacks.

So in Xcode click on File\New\File… and choose the C++ Class template under iOS\C and C++.

Click Next, name it HudLayer and click Create.

Open up HudLayer.h, and replace the contents with the following:

#ifndef __HUDLAYER_H__
#define __HUDLAYER_H__

#include "cocos2d.h"

using namespace cocos2d;

class HudLayer : public cocos2d::CCLayer
{
private:
    CCLabelTTF *_label;
    
public:
    // Method 'init' in cocos2d-x returns bool, instead of 'id' in cocos2d-iphone (an object pointer)
    virtual bool init();
    
    // there's no 'id' in cpp, so we recommend to return the class instance pointer
    static CCScene* scene();
    
    // a selector callback
    void menuCloseCallback(CCObject* pSender);
    
    // preprocessor macro for "static create()" constructor ( node() deprecated )
    CREATE_FUNC(HudLayer);
    
    void numCollectedChanged (int numCollected);
};

#endif // __HUDLAYER_H__

This creates a class that derives from CCLayer, the Cocos2D-X class that represent a layer. It creates a private instance variable to keep track of the label to display, and has a helper function to update the number to display in the label.

Next replace HudLayer.cpp with:

#include "HudLayer.h"

using namespace cocos2d;

bool HudLayer::init()
{
    if (CCLayer::init()) {
        CCSize winSize = CCDirector::sharedDirector()->getWinSize();
        
        _label = new CCLabelTTF();
        _label->initWithString("0", "Verdana-Bold", 18.0);
        _label->setColor(ccc3(0,0,0));
        
        int margin = 10;
        _label->setPosition(ccp(winSize.width - (_label->getContentSize().width/2) - margin, _label->getContentSize().height/2 + margin));
        this->addChild(_label);
    }
    
    return true;
}

void HudLayer::numCollectedChanged(int numCollected)
{
    CCString *labelCollected = new CCString();
    labelCollected->initWithFormat("%d",numCollected);
    _label->setString(labelCollected->getCString());
}

In init, you create a label and add it as a child of the layer. In numCollectedChanged, you update the text of the label.

Now let’s put this layer to use. In HelloWorldScene.h, import your new file at the top:

#include "HudLayer.h"

And declare two new private properties – for your new layer, and the amount of watermelons collected:

HudLayer *_hud;
int _numCollected;

In HelloWorldScene.cpp, add this code to the CCScene * scene() method right before the return:

HudLayer *hud = new HudLayer();
hud->init();
scene->addChild(hud);
layer->_hud = hud;

This creates your layer and adds it to the scene. It also sets the hud variable on your main layer to the newly created layer, so you have a way to talk to it.

Finally, add this code to setPlayerPosition, in the case where a tile is collectable:

 
_numCollected++;
_hud->numCollectedChanged(_numCollected);

Here you’ve modified the HelloWorldScene to call a method on the HudLayer when the count changes, so it can update the label accordingly.

Build and run the project, and if all goes well you should see a melon counter in the bottom right!

Melon counter label

Gratuituous Sound Effects and Music

You know this wouldn’t be a game tutorial from this site without completely unnecessary but fun sound effects and music :]

Simply make the following changes to HelloWorldScene.cpp:

// At top of file
#include "SimpleAudioEngine.h"
 
// At top of init method
CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadEffect("pickup.caf");
CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadEffect("hit.caf");
CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadEffect("move.caf");
CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic("TileMap.caf");
 
// Inside setPlayerPosition, in case of collidable tile
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("hit.caf");
 
// Inside setPlayerPosition, in case of collectable tile
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("pickup.caf");
 
// Inside setPlayerPosition, right before setting player position
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("move.caf");

Now your ninja can groove happy as he eats!

Where To Go From Here?

That’s it for this tutorial series, at least for now. You should have a good grasp on the most important concepts related to using tile maps in Cocos2D-X at this point.

Here is a copy of the Tile-Based Cocos2D-X game that you’ve developed so far.

If you have any additional tips or suggestions for how to effectively use Tiled or tile-based maps in Cocos2D-X effectively, or if you’ve used or are planning to use tile-based maps in your projects, please share below!

Jorge Jordán

Contributors

Jorge Jordán

Author

Over 300 content creators. Join our team.