Cocos2d-xを半日触ってみた　～触った感想ハマリポイント～

Cocos2d-xという名前だけは、聞いたことがあったんですが、実際に触ったことはなかったので、実際の触った感想や、ハマりポイントをざっと書いておこうと思います。
ハマリポイントは、もしかすると解決方法として正しくない項目もあるかもしれないので、
間違っていたら指摘いただけると嬉しいです。

本記事は、試したことを順序通りかいてますが、内容スッカスカなので、
インストールを目的にしてる人はなんの役にも立ちません。
最後にAndroidビルドに無駄に手こずったので、Androidビルドの件含め、ハマリポイントは最後のほうに少し記載してるので、そちらは参考になるかもしれません。

## インストール
簡単でした。
cocos2d-xを公式で落としてきて、「setup.py」を実行して、質問に答えながらポチポチするだけで、
インストールとセットアップは完了しました。

※cocos studio を使用する場合は、cocos studio 側がどうも cocos2d-x を手動で入れた場合
　認識してくれないようなので、cocos studio 側でもインストールを行う必要がありました。
　先に cocos studio をいれて、cocos2d-x を入れたほうがいいのかもしれませんが、未検証です。

## さっそく使ってみる
コマンドプロンプトを立ち上げて、以下の様なコマンドを叩くだけでプロジェクトを作成できます。
```lang:コマンドプロンプト
> cocos new MyGame -p com.mycompany.mygame -l cpp -d c:\cocos-projects
```
これで c:\cocos-projects 以下に MyGame というプロジェクトが作成されます。

## ビルドしてみる＆作ってみる
c:\cocos-projects\MyGame\proj.win32 に丁寧にも sln 形式の Visual Studio 用の
プロジェクトがいるので、普通にこいつをひらくことで Visual Studio でビルドができます。
※ビルドには多少時間を要します。

ビルドが終われば実行ファイルが普通に作成されます。楽ですね。

ただ私はここで疑問が浮かびました。

　わたし「で、どうやってゲームをつくっていくんじゃ？？？」

まさか、コードレベルでゴリゴリ UIパーツ を create して setPosition して setSize してssetAnchor を自分で、自分でイベント登録かいてとかしないといけないのか？　と。
実際そうなんですが、これは cocos studio で UI を設計することで、ある程度の UI設計は省略可能です。

なので、cocos studio 上でプロジェクトを作成してしまえばかなり作業が捗るかと思います。

## ハマった点

### addTouchEventListener ではタップ座標を取れない
かなり調べたのですが、タップ座標を取る方法がでてきませんでした。
特定のオブジェクトをタップ時にどの位置をタップしたかをみて、処理を分岐させる。
という処理が必要だったので、しかたなく EventListenerTouchOneByOne::create() を用いて対応しました。

また、cocos studio で配置した Panelが悪いのか、Panelをタップしてもイベントが飛んでこなかったので、コード上で Panel を配置したところ、うまくイベントが拾えるようになりました。

```lang:test.cpp
//タッチイベント
auto listener1 = EventListenerTouchOneByOne::create();
listener1->setSwallowTouches(true);
listener1->onTouchBegan = [=](Touch* touch, Event* event) {
    return true;
}
listener1->onTouchMoved = [](Touch* touch, Event* event) {};
listener1->onTouchEnded = [=](Touch* touch, Event* event) {};

// レイアウト作成
auto rboard = ui::Layout::create();
rboard->setSize(cocos2d::Size(600, 600));
rboard->setAnchorPoint(Vec2(0, 0));
rboard->setPosition(cocos2d::Size(20, 20));
rboard->setTag(1000000);
mainScene->addChild(rboard,0);

_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, rboard);

```
該当箇所のみ抜粋。

### onTouchBegan で強制 true をかえす場合はきをつけろ
あたりまえっちゃあたりまえですが、addTouchEventListener を使用した物がある場合、優先順位などによっては、正常にイベントが捕捉できなくなります。

なので、onTouchBegan で対象のオブジェクトがタップされているか？などの判定をする処理は必ず実装しましょう。

### Android のビルドが通らん

だいたいは以下を見直すことで改善できます。
- Android SDKのバージョン
- Android NDKのバージョン
- 環境変数の設定

Android NDK は古すぎるとだめなようなので、古すぎる場合は更新しないとダメそうです。
環境変数は、設定ミスした場合、Not Found ではなく

```コマンドプロンプト
> build_native.py
Please use cocos console instead.

Building mode: debug
Using Eclipse project : C:\<project dir>\proj.android
Android platform not specified, searching a default one...
Can't find right Android-platform for project : 'C:\<project dir>\proj.android'. The Android-platform should be equal/larger than 20.
Traceback (most recent call last):
  File "C:\<project dir>\proj.android\build_native.py", line 43, in <module>
    build(opts.build_mode)
  File "C:\<project dir>\proj.android\build_native.py", line 28, in build
    raise Exception("Build dynamic library for project [ " + app_android_root + " ] fails!")
Exception: Build dynamic library for project [ C:\<project dir>\proj.android\../ ] fails!
```
みたいなのがでることがあります。
Can't find right Android-platform for project : 'C:\<project dir>\proj.android'. The Android-platform should be equal/larger than 20.
ここで SDK のバージョンが古いのか NDK のバージョンが古いのかをまず疑いそうですが、
SDK のroot パスの環境変数の記載ミスでもこのエラーがおきるので注意が必要です。
私の場合、本来
ANDROID_SDK_ROOT= F:\android\android_sdk\sdk
とするところが
ANDROID_SDK_ROOT= F:\android\android_sdk
となってました。
恥ずかしい限りです。

## 最後に
まだ半日程度しか触ってないので、シーン切り替えもわかってませんし、使い方も不明瞭なところが多いのですが、同じ処理で、各プラットフォームに簡単に対応できるのは良いですね。
気になった点としては、GUI上で作業できる項目の多さはやはりUnityが圧倒的だなという印象を受けました。
どうにもこうにもコードをゴリゴリ書いていかないといけないので、とっつきはよくないですね。
そこさえなんとかなれば、更に使用者が増えるのでは？と感じました。

時間があるときにでももう少し触ってみようと思います。