cocos2d-xのSimpleGameに機能を追加する

SimpleGameを一通り理解できたので、次は練習として機能を追加します。

開始画面と開始ボタンの追加

画面がSceneとLayerを作って、
ボタンは本来ゲーム中の終了ボタンの作り方を使って、
ボタンが押されたときのゲームSceneに切り換える関数を追加する。
最後に、終了Sceneの後はゲームSceneではなく、開始Sceneに戻らせます。
スクリーンショット 2014-08-23 17.58.58
開始Sceneの定義です。

class StartLayer : public cocos2d::CCLayerColor
{
public:
	CREATE_FUNC(StartLayer);
	virtual bool init();
	static cocos2d::CCScene* scene();
	// 開始ボタンの動作を定義する関数。
	virtual void menuStartCallback(cocos2d::CCObject* pSender);
	// ラベル「開始ボタンを押して」を表示する。結果画面をまねする。
	CC_SYNTHESIZE_READONLY(cocos2d::CCLabelTTF*, _label, Label);
};

AppDelegate::applicationDidFinishLaunching()の中に
アプリ起動のシーンを開始シーンにします。

CCScene *pScene = StartLayer::scene();
pDirector->runWithScene(pScene);

開始ボタンのコードです。画像はゲームのclose画像をそのまま使いました。

CCMenuItemImage *pStartItem = CCMenuItemImage::create("CloseNormal.png", "CloseSelected.png",
                                                      this, menu_selector(StartLayer::menuStartCallback));
CC_BREAK_IF(! pStartItem);
// pStartItem->setPosition()位置の設定を省略した
CCMenu* pMenu = CCMenu::create(pStartItem, NULL);

ボタンが押したら、このコールバック関数を呼び出して、ゲームのシーンに切り換える。

void StartLayer::menuStartCallback(CCObject* pSender)
{
    CCDirector::sharedDirector()->replaceScene(HelloWorld::scene());
}

スコアを計算する機能

まずはHelloWorldクラスのにscoreプロパティを追加する。
CC_SYNTHESIZEマクロを使用します。
一番目はプロパティのタイプ。
二番目はプロパティ名。定義されるのはprotectedプロパティ。
三番目はsetXXXとgetXXXのXXX。つまりsetScoreとgetScore関数が定義される。

CC_SYNTHESIZE(int, _score, Score);

スコアの計算方法は自分で考えて設定します。
僕が使用する方法は:スコア=当たった敵のX座標
HelloWorldのupdateGame関数にメソッドを追加。

if (projectileRect.intersectsRect(targetRect))
{
	targetsToDelete->addObject(target);
	// 下記は追加コード。敵が当たった毎に、HelloWorldレイヤーに保存されているscoreに敵のX座標を加算する。
	this->setScore(this->getScore() + (int)target->getPositionX());
}

最高スコアを記録する

勝利できれば最高スコアが表示されます。
最高スコアを保持し続けなければならないので、
CCUserDefault::sharedUserDefault()で保持する。

int GameOverLayer::setHighscore(int newScore)
{
    // CCUserDefault::sharedUserDefault()はユーザのデータを Key と Value のペアの形式で保存する
    // maxで新しいスコアと今までの最高スコアを比較し、大きい方をhighScoreに入れる
    CCUserDefault::sharedUserDefault()->setIntegerForKey("highScore", MAX(newScore, CCUserDefault::sharedUserDefault()->getIntegerForKey("highScore")));
    // 保存した後、flushでコミットする
    CCUserDefault::sharedUserDefault()->flush();
    // 最高スコアを戻し、最高スコアを画面に表示する時に使う
    return CCUserDefault::sharedUserDefault()->getIntegerForKey("highScore");
}

ゲームごとのスコアも、最高スコアもできたので、画面に表示させればいいです。
表示方法は結果画面のYou Win, You Lose文字のまねをして作りました。
スクリーンショット 2014-08-23 18.00.04

今回苦労したこと

今仕事もプログラマーなので、作り方について悩まなかった。
だが、普段JavaとWeb系なので、C++は不慣れです。
検索してもなかなか的中できなくて、結構苦労しました。

Javaの文字列連結は「+」でいいですが。

String str = "score : " + 1;

同じ書き方なら、「core : 」という文字列になった。
どうやら、「score : 」のポインタが増えたようです。
原因はCCLabelTTFが受け取れる文字列はchar *です。

gameOverScene->getLayer()->getScoreLabel()->setString("score : " + 1);

Cの連結方法はsprintf()です。

// 文字列と数字を連結するため
char str[256];
sprintf(str, "score : %d" + 1);

ある程度に勉強できたら、文字列を一回まとめたほうがいいです。
また、検索したらObjective-Cの情報も多かった、やはりObjective-Cを読める方がいいと考えた。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


*

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>