cocos2d-x version2.2.3からversion3.2rc0への移行メモ

cocos2d-x を version2.2.3からversion3.2rc0に移行しました
C++C++11としての記述が可能となり、cocos2d-xの記述についても変更した点についてまとめました
これが正しい方法である保証はありませんので、参考程度の見ていただければと思います

型推論

初期化を含んだ宣言では、型名を使わずautoで宣言できるようになった

auto sprite = Sprite::create("FILENAME");

基本的にCCプレフィックスを削除

基本的にクラスのCCプレフィックスを削除する
ただし例外として、以下のクラスやマクロについてはプレフィックスを削除するだけではない

v2.2.3 v3.2rc0
CCObject Ref
CCLabelXXX Label
CCArray Vector
CCDictionary Map
CCString std::string
CCPoint Vec2
CCString
CCInteger
CCFloat
CCDouble
CCBool
etc.
Value
ccpマクロ Vec2クラスのコンストラクタVec2()
ccc3マクロ Color3BのコンストラクタColor3B()
ccc4マクロ Color4BのコンストラクタColor4B()
CCHogeMakeマクロ HogeクラスのコンストラクHoge()
cocos2d::cc_timeval timeval

など

Labelついて

  • LabelXXXも利用できるが、3.2rc0では既にdeprecated指定
  • 関数名の変更
v2.2.3 v3.2rc0
setFontSize() setSystemFontSize()
setFontFillColor() setTextColor()
enableStroke() enableOutline()

CCArray は Vector

  • 基本的にVectorに変更
  • Vector vのように定義
  • 配列にもたせられる型はRef Classを継承したもののみ
  • 現状Value型はRefを継承していないため、std::vectorを使用、もしくはCCArrayのままで警告を無視

CCDictionary は Map に

  • 基本的にMapに変更
  • Map mのように定義
  • マップのValueにもたせられる型はRef Classを継承したもののみ
  • 現状Value型はRefを継承していないため、std::mapを使用、もしくはCCDictionaryのままで警告を無視

CCString は std::string に

使い方

std::string str = Value("string");
std::string str = StringUtils::format("%d point", point);

sharedXXX() は getInstance() に

CCDirector::sharedDirector->setAnimationInterval(1.0/60);

から

Director::getInstance->setAnimationInterval(1.0/60);

といった書き方に変更

Deprecated警告を消したい場合

基本的には上記の方法で修正するべきだが、修正箇所が多いもの(CCArrayやCCDictionaryなど)は、次の文で挟むことで警告を消すことができる。

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
// ここにDeprecatedされている処理
#pragma clang diagnostic pop

callbackについて

ラムダ式によるコールバックを記述できるようになった

MenuItem *item = MenuItem::craete(this, menu_selector(ClassName::functionName));

  • 例1
ccMenuCallback callback = [](Ref *obj){
	// do something
};
auto item = MenuItem::create(“filename”, “filename”, callback);
  • 例2
auto item = MenuItem::create(“filename”, “filename”, [](Ref *obj){
	// do something
});

CCCallFunk系の変更

CCCallFunc

CCCallFunc *func = CCCallFunc::create(this, callfunc_selector(Hoge::function));

auto func = CallFunc::create(CC_CALLBACK_0(Hoge::function, this));

または

auto func = CallFunc::create([this](){
    this->function();
});

CCCallFuncN

CCCallFuncN *func = CCCallFuncN::create(this, callfuncN_selector(Hoge::function));

auto func = CallFuncN::create(CC_CALLBACK_1(Hoge::function, this));

または

auto func = CallFuncN::create([this](Ref *sender){
    this->function(sender);
});

などのように変更

タッチイベントの実装

以前記事を書いたので詳細はこちら

タッチイベントの登録と削除 [EventListener] - よく寝てちょっと食べる

まとめ

ひとまずはこの辺が主な変更すべき点でしょうか
Deprecated指定となったクラスの新たな名前を調べたい場合は、CCDeprecated.hを見てみると大体書いてあることが多いです

タッチイベントの登録と削除 [EventListener]

cocos2d-x を version2.2.3からversion3.2rc0に移行してみました
タッチイベントについて大幅な変更があったのでメモしておきます

TestLayer.h
v2.2.3

public:
    virtual bool ccTouchBegan(cocos2d::CCTouch *touch, cocos2d::CCEvent *event);
    virtual void ccTouchMoved(cocos2d::CCTouch *touch, cocos2d::CCEvent *event);
    virtual void ccTouchEnded(cocos2d::CCTouch *touch, cocos2d::CCEvent *event);
    virtual void ccTouchCancelled(cocos2d::CCTouch *touch, cocos2d::CCEvent *event);

v3.2rc0

private:
    cocos2d::EventListenerTouchOneByOne *eventListener;
public:
    bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *event);
    void onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *event);
    void onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *event);
    void onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *event);

TestLayer.cpp - タッチイベントの登録
v2.2.3

void TestLayer::onEnter()
{
    Node::onEnter();

    setTouchEnabled(true);
    setTouchMode(kCCTouchesOneByOne);
}

v3.2rc0

void TestLayer::onEnter()
{
    Node::onEnter():

    auto dispatcher = Director::getInstance()->getEventDispatcher();
    eventListener = EventListenerTouchOneByOne::create();
	
    eventListener->onTouchBegan		= CC_CALLBACK_2(TestLayer::onTouchBegan, this);
    eventListener->onTouchMoved		= CC_CALLBACK_2(TestLayer::onTouchMoved, this);
    eventListener->onTouchEnded		= CC_CALLBACK_2(TestLayer::onTouchEnded, this);
    eventListener->onTouchCancelled	= CC_CALLBACK_2(TestLayer::onTouchCancelled, this);
	
    dispatcher->addEventListenerWithSceneGraphPriority(eventListener, this);
}

TestLayer.cpp - タッチイベントの削除
v2.2.3

void TestLayer::Hoge()
{
    setTouchEnabled(false);
}

v3.2rc0

void TestLayer::Hoge()
{
    auto dispatcher = Director::getInstance()->getEventDispatcher();
    dispatcher->removeEventListener(eventListener);
    // すべてのタッチイベントを削除する場合はこっち
    // dispatcher->removeEventListenersForTarget(this);
}

cocos2d-xのプロジェクトをXcode5上で途中からGit管理

cocos2d-xのプロジェクトをXcode5上で途中からGit管理しようと思ったのですが、
初Gitということもあって少しややこしかったのでメモ

Source Controlの箇所について、最初はこんな感じになっています。

1. terminalでgitを使う準備をする

http://sourceforge.net/projects/git-osx-installer/ からgitをダウンロードし、terminalでgitコマンドを使えるようにしておきます

2. .gitディレクトリを作成する

cocos2d-xプロジェクトの.xcodeprojファイルがあるフォルダ ではなく"Classes"ディレクトリのあるディレクトにterminal上で移動してから以下の3つのコマンドを順番に入力

$ git init
$ git add .
$ git commit -m "initial commit"

(initial commitの部分は任意の文字列)

これで、ディレクトリ内に.gitディレクトリが生成されます

3. Xcode上で確認

Xcodeを完全に閉じてから(⌘Qなどで)起動し直します。
すると、次のようになっていました。

「あれ?なんかエラー出てる?」と思いましたが、ここからファイル選択したり、少し記述してみたりすると

Repositoryの横の●が緑色の表示になり、無事成功しました。

CocoaPods導入

CocoaPodsを導入する際数カ所引っかかったのでメモとして残しておきたいと思います


1. まずはinstalll

$ sudo gem install cocoapods

このままだと開始まで時間があって動いてるかどうかわからないので、-Vオプションを付けるとよいです

$ sudo gem install cocoapods -V

2. 念のためアップデート

$ sudo gem update --system

3. セットアップ

$ pod setup

4. 目的の.xcodeprojファイルがあるディレクトリにPodfile(拡張子なし)を作成

platform :ios, '6.0'
pod 'BlocksKit'

みたいな感じ。BlocksKitの部分は導入したいFrameworkの名前を書きます。
ここで、テキストエディットなんか使ってると
これがこんな感じに勝手に変換されてしまうことがあるので、Control-'を使って自動変換されないよう入力します


5. 作成したら、.xcodeprojファイルがあるディレクトリでinstall

$ pod install

6. .xcworkspaseが生成されているのでそれを開き直す

7. Frameworks内libPods.aが赤字になっている(見つからない)ので次の操作を順番に行う

  • PodsプロジェクトのBuild Settings内ArchitecturesとOther Linker Flagsをすべて削除(Architecturesはデフォルト値になる)
  • PodsプロジェクトのBuild Active Architecture OnlyのFlagをNoに変更
  • Xcode -> Preference -> Locations -> Derived DataのAdvaned... -> CustomのプルダウンメニューをRelative to Workspaceに -> Done
  • Product -> Scheme -> Manage Schemes -> Podsにチェック
  • Product -> Scheme -> Podsを選択
  • Product -> Destination -> 自分のiOS端末 または iOS Deviceを選択
  • Product -> Archive

これで赤字が解消されるはずです

8. これで自分は無事ビルドができました

CCArrayの生成方法

いっつも忘れるので備忘録としてメモしておきます

基本

// 生成とretain
array = CCArray::create();
array->retain();

/* 全ての処理 */

// 後処理
CC_SAFE_RELEASE_NULL(array);

スコープを抜けたら破棄しても良い場合

// 生成
array = CCArray::create();

/* 処理 */

retainしないとスコープ抜けた時破棄されて次の参照時にクラッシュします。

cocos2d-xでのplist読み込み

例えば以下のStageData.plistがあった時

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
	<dict>
		<key>name</key>
		<string>STAGE 1</string>
		<key>param1</key>
		<integer>1</integer>
		<key>param2</key>
		<real>40.23</real>
	</dict>
	<dict>
		<key>name</key>
		<string>STAGE 2</string>
		<key>param1</key>
		<integer>2</integer>
		<key>param2</key>
		<real>35.12</real>
	</dict>
	.
	.
	.
</array>
</plist>

STAGE 1のデータを読み込む際はこんな感じになります。

CCArray		*items		= CCArray::createWithContentsOfFile("StageData.plist");
CCDictionary	*dic			= (CCDictionary *)items->objectAtIndex(0);
CCString		*name		= (CCString *)dic->objectForKey("name");
int			param1		= ((CCString *)dic->objectForKey("param1"))->intValue();
double		param2		= ((CCString *)dic->objectForKey("param2"))->doubleValue();

あくまでplist側での型がintegerやrealでも、CCStringにキャストした後にintValue()とかdoubleValue()で取得すると問題なく動くようです。

CCLabelTTFに輪郭線を描く

setColorをしてしまうと塗りとストローク両方の色を指定することになってしまうので

CCLabelTTF *label = CCLabelTTF::create("test", "Arial", 24);
label->setFontFillColor(ccc3(255, 255, 255));
label->enableStroke(ccc3(0, 0, 0), 1.0f);

こうすることで、塗り部分とストローク部分を別々に指定するようです。