手元に清水 友晶さんの『cocos2d-x入門』があるので、この書籍のサンプルを実装してみます。

2013発売であり、コードもcocos2d-x 2.xの時代のもので、そのままでは現在の3.x系で使うことができません。
カンを取り戻すのと、3.x系の変更を把握するために、サンプルコードを3.x系で書き直してみました。

環境

  • Windows 10
  • cocos2d-x 3.5
  • Android NDK r10d

シーン生成

// 2.x
cocos2d::CCScene* scene();

// 3.x
static cocos2d::Scene* createScene();
// 2.x
if ( !CCLayer::init() )

// 3.x
if ( !Layer::init() )

Director

一番出てくるもの、、、CCDirectorがシングルトンになったとかなんとか。

// 2.x
CCSize winSize = CCDirector::sharedDirector()->getWinSize();

// 3.x
Size winSize = Director::getInstance()->getWinSize();

スプライト

autoが利用できるようになり、Spriteの生成がとっても楽になりました。
2.x系はCCSちゅうのがタイピングし辛くて、、、これだけでCocosが嫌でした。

// 2.x
CCSprite* bg = CCSprite::create("bg.png");

// 3.x
auto bg = Sprite::create("bg.png");

ccp または CCPointMake

// 2.x
bg->setPosition(ccp(x, y));

// 3.x
bg->setPosition(Vec2(x, y));

CCArray

基本型クラスがあらかた非推奨に。
CCArraystd::vector<int>を使います。

// 2.x
CCArray* numbers = CCArray::create();
numbers->addObject(CCInteger::create(i));
int number = ((CCInteger*)numbers->objectAtIndex(index))->getValues();
numbers->removeObjestAtIndes(index);

// 3.x
std::vector<int> numbers;
numbers.push_back(i);
int number = numbers[index];
numbers.erase(numbers.begin() + index);

タッチイベント / イベントリスナ

タッチイベント、イベントリスナにも大きな変更がありました。

まずヘッダファイル

// 2.x
virtual bool ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);
virtual void ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);

// 3.x
virtual bool onTouchBegan(cocos2d::Touch *pTouch, cocos2d::Event *pEvent);
virtual void onTouchEnded(cocos2d::Touch *pTouch, cocos2d::Event *pEvent);

cppファイル

// 2.x
setTouchEnabled(true);
setTouchMode(kCCTouchesOneByOne);

// 3.x
auto dispacher     = Director::getInstance()->getEventDispatcher();
auto eventListener = EventListenerTouchOneByOne::create();

eventListener->onTouchBegan = CC_CALLBACK_2(GameScene::onTouchBegan, this);
eventListener->onTouchEnded = CC_CALLBACK_2(GameScene::onTouchEnded, this);

dispacher->addEventListenerWithSceneGraphPriority(eventListener, this);

ログ

大文字と小文字、、、これは検索で調べるのが難しかったです。
思いのほか詰まってしまった点です。

// 2.x
CCLog("log message");

// 3.x
CCLOG("log message");

あたり判定

Rectを使ったあたり判定。これはCCをカットするだけのイメージですね。

// 2.x
CCNode* pCard = this->getChildByTag(nextNumber);
if (!pCard)
{
    return;
}
CCRect cardRect = pCard->getBoundingBox();
if (cardRect.containsPoint(touchPoint))

// 3.x
auto pCard = this->getChildByTag(nextNumber);
if (pCard == NULL)
{
    return;
}

Rect cardRect = pCard->getBoundingBox();
if (cardRect.containsPoint(touchPoint))

MenuItemLabel

CCMenuItemLabelの非推奨が上手く解消できず、結局コールバックで対処しました。

// 2.x
CCMenuItemLabel* retryItem = CCMenuItemLabel::create(retryLabel, this, menu_selector(GameScene::tapRetryButton));

// 3.x
auto retryItem  = MenuItemLabel::create(retryLabel, [this](Ref* unused) -> void {
    tapRetryButton(unused);
});
// 本当は以下のようなコードで動くはず?
// auto retryItem  = MenuItemLabel::create(retryLabel, CC_CALLBACK_1(GameScene::tapRetryButton, this));

文字とラベル

文字はstd::stringを使います。
書き方がシンプルになりますね。

また文字の整形にはStringUtilsクラスが用意されています。

// 2.x
CCString*   timeString = CCString::createWithFormat("%8.1fs", gametime);
CCLabelTTF* timerLabel = (CCLabelTTF*)this->getChiledByTag(tagGametimeLabel);
if (timerLabel)
{
    timerLabel->setString(timeString->getCString());
}
else
{
    timerLabel = CCLabelTTF::create(timeString->getCString(), "Arial", 24.0);

// 3.x
std::string timeString = StringUtils::format("%8.1fs", gameTime);
auto timerLabel        = (Label*)this->getChildByTag(tagGametimeLabel);
if (timerLabel)
{
    timerLabel->setString(timeString);
}
else
{
    timerLabel = Label::createWithTTF(timeString, "Arial", 24.0);

UserDefault

音量などの状態を保存するためによく使うUserDefault
Directorと同じようにgetInstanceを使う形になりました。

// 2.x
CCUserDefault *userDefalt = CCUserDefault::sharedUserDefault();

// 3.x
auto userDefault = cocos2d::UserDefault::getInstance();

ビルドしてAndroidの実機で挙動をチェック。
無事、サンプルの1つ目は完成しました。

このサンプルを改造するだけでも、ごくシンプルなアプリなら作ることができそうです。

スポンサーリンク
ad_336
ad_336
  • このエントリーをはてなブックマークに追加
  • Evernoteに保存Evernoteに保存
スポンサーリンク
ad_336