为samplegame添加一个失败/成功的场景
详见:http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Chapter_7_-_Some_Icing_on_the_Cake
The simple game is completed basically, but we could add some adornments to make the game seem more professional.
In this chapter, we will add a new scene. When a certain quantity of monsters are killed, show “You Win” on the screen, and when there is a monster runs out of the left of the screen, show “You Lose”.
Now create two files GameOverScene.cpp and GameOverScene.h in the Classes directory.
For GameOverScene.h:
#ifndef _GAME_OVER_SCENE_H_
#define _GAME_OVER_SCENE_H_
#include "cocos2d.h"
class CGameOverLayer : public cocos2d::CCLayerColor
{
public:
CGameOverLayer() : _label(NULL) {};
virtual ~CGameOverLayer();
bool init();
void gameOverDone();
CC_SYNTHESIZE_READONLY(cocos2d::CCLabelTTF*, _label, Label);
CREATE_FUNC(CGameOverLayer);
};
class CGameOverScene : public cocos2d::CCScene
{
public:
CGameOverScene(void) : _layer(NULL) {};
virtual ~CGameOverScene();
bool init();
CC_SYNTHESIZE_READONLY(CGameOverLayer*, _layer, Layer);
CREATE_FUNC(CGameOverScene);
};
#endif //_GAME_OVER_SCENE_H_
For GameOverScene.cpp:
#include "GameOverScene.h"
#include "HelloWorldScene.h"
using namespace cocos2d;
CGameOverLayer::~CGameOverLayer()
{
if (_label)
{
_label->release();
_label = NULL;
}
}
bool CGameOverLayer::init()
{
bool bRet = false;
do
{
CC_BREAK_IF(! CCLayerColor::initWithColor( ccc4(255, 255, 255, 255) ));
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
_label = CCLabelTTF::create("", "Artial", 32);
_label->retain();
_label->setColor( ccc3(0, 0, 0) );
_label->setPosition( ccp(winSize.width/2, winSize.height/2) );
this->addChild(_label);
this->runAction( CCSequence::create(
CCDelayTime::create(3),
CCCallFunc::create(this,
callfunc_selector(CGameOverLayer::gameOverDone)),
NULL));
bRet = true;
} while (0);
return bRet;
}
void CGameOverLayer::gameOverDone()
{
CCDirector::sharedDirector()->replaceScene(HelloWorld::scene());
}
//
CGameOverScene::~CGameOverScene()
{
if (_layer)
{
_layer->release();
_layer = NULL;
}
}
bool CGameOverScene::init()
{
bool bRet = false;
do
{
_layer = CGameOverLayer::create();
_layer->retain();
this->addChild(_layer);
bRet = true;
} while (0);
return bRet;
}
We add a variable in HelloWorldScene to count how many monsters are killed by the hero.
protected:
int _projectilesDestroyed;
And Initialize it in HelloWorld::HelloWorld(),
_projectilesDestroyed = 0;
Include GameOverScene.h in HelloWorldScene.cpp,
#include "GameOverScene.h"
After removeChild(target) in the targetsToDelete for loop of HelloWorld::update(), add the codes below to check the win condition.
CCARRAY_FOREACH(targetsToDelete, jt)
{
CCSprite *target = dynamic_cast<CCSprite*>(jt);
_pTargets->removeObject(target);
this->removeChild(target, true);
_projectilesDestroyed++; // <--
}
if (_projectilesDestroyed > 5)
{
CGameOverScene *gameOverScene = CGameOverScene::create();
gameOverScene->getLayer()->getLabel()->setString("You Win!");
CCDirector::sharedDirector()->replaceScene(gameOverScene);
}
Add the codes below to check the failure condition in the “if (sprite->getTag() == 1)” conditional of spriteMoveFinished(),
if (sprite->getTag() == 1)
{
_pTargets->removeObject(sprite);
CGameOverScene *gameOverScene = CGameOverScene::create();
gameOverScene->getLayer()->getLabel()->setString("You Lose!");
CCDirector::sharedDirector()->replaceScene(gameOverScene);
}
Tip
In cocos2d-x, we should call release() in two cases:
• The object is newed by ourself, for example, CCSprite *sprite = new CCSprite();
• The object is created by a static function, for example, CCSprite *sprite = CCSprite::spriteWithFile(...), in this case, we don’t need to release, but when sprite->retain() is called, then sprite->release() should be called too.
什么情况下需要使用 retain()呢??????