iOSとアンドロイド、2大プラットホーム対応のゲーム開発が可能な『cocos2d-x』。国内外を問わず採用事例も多い人気フレームワークだが、その次期メジャーバージョンアップである3.0のリリースが近づいている。本稿ではcocos2d-x自体の紹介と共に、バージョン3.0の注目機能を取り上げてみたいと思う。要チェックだ!
◆cocos2d-xとは?
cocos2d-xはMITライセンス下で配布されているゲーム開発用フレームワークであり、github上で誰でも参加できるオープンなスタイルで開発が進められている。すでにご存知の方も多いと思われるが、改めて紹介しておこう。
cocos2d-x最大の特徴はiOS、AndroidをはじめMacやWindows向けのゲームも開発できるマルチプラットホーム対応だ。開発言語には、C++をはじめLua、JavaScriptなどが使用できる。
エイリムの『ブレイブフロンティア』、Cygamesの『三国志パズル大戦』、同じくCygamesとスクウェア・エニックスによる『ドラゴンクエストモンスターズ スーパーライト』など、大型タイトルでも着実に採用が進んでいる。弊社もスクウェア・エニックスとの共同開発である新タイトル「DRAGON SKY」をはじめ、新開発はすべてcocos2d-xで行っている。
数々の採用事例については、公式サイトをご覧いただくのが分かりやすいだろう。
解説書籍も『cocos2d-xによるiPhone/Androidアプリプログラミングガイド』(清水 友晶)や『Cocos2d‐x開発のレシピ―iOS/Android対応』(松浦 晃洋)など数冊が発刊されており、日本ユーザー会によるイベントも盛況。第七回テックヒルズでUnityなど他のゲームエンジンとの比較が話題になったのも記憶に新しいところだ。
このような盛り上がりを見せる中発表されたバージョン3.0、2014年1月27日にはベータ2がリリースされた。安定版のリリースは、ロードマップによれば2014年2月25日ともう目の前だ。当然注目度も高いが、いったい何が変わるのだろうか?
◆バージョン3.0で何が変わる?
まずはバージョン3.0のリリースノートをご覧いただきたい。ハイライトを見るだけでも、非常に多くの改善がなされている事がわかる。
<ハイライト抄訳>
・Objective-C的なパターンをC++11的なパターンへ
・ラベルの改善
・レンダラーの改善
・新しいイベントディスパッチャー
・物理演算の統合
・新しいGUI
・JavaScriptリモートデバッガー
・リモートコンソールのサポート
・画像処理のリファクタ(メモリの即時解放、各種画像フォーマットに対する統一的なAPI)
・自動生成されるLua bindings(LuaJavaBridgeとLuaObjcBridge)
・テンプレート対応のコンテナー
この中でも特に注目度が高そうな、C++関連、レンダラー、イベントディスパッチャー、ラベルについて、これまでのバージョンと比較しつつ詳しく見てみよう。
◆C++とcocos2d-x
そもそもcocos2d-xはObjective-C&iOS向けのフレームワークである『cocos2d for iPhone』をベースとしている。『cocos2d for iPhone』と違い、開発言語にC++を採用することで、Android向けの開発も同時に出来るという大きなメリットを手に入れたわけだ。こういった経緯から、C++上のフレームワークであるにも関わらず、cocos2d-x バージョン2系は各所にObjective-C的な面を数多く残している。
だが、そのためにC++との親和性が低いうえにObjective-Cで使えた便利機能が無い、という「悪いとこ取り」がまま発生していた。
バージョン3.0ではC++との融和が劇的に進み、C++自体もレガシーなC++98系ではなく、C++11がデフォルトになった。これによりコード全体の一貫性や簡潔性、ロバストネスの向上を実現している。以下で具体的に紹介していこう。
◆名前空間と命名規則の修正
これまでのcocos2d-xでは、各クラスに「CC」などのプレフィックスがつけられていた。しかし、そもそも、Objective-Cに名前空間がないためにプレフィックスがついていたのであって、C++にて実装する際には名前空間さえあればよい道理である。
そのためバージョン3.0では「cocos2d」名前空間に含まれるクラスから「CC」プレフィックスが取り除かれた他、「DrawPrimitives」「GL」などの名前空間が新たに追加され、既存のクラス・メソッド・定数の整理が行われた。例えばcocos2d::CCSpriteクラスはcocos2d::Spriteクラスに変更されている。
◆関数定義の改善
Objective-Cスタイルの、プロパティ名そのままのアクセサメソッドは無くなり、getter/setterにはget/setのプレフィックスがついた。またシングルトンへのアクセサはgetInstance()メソッドに統一されている。これにより、例えば、node->boundingBox()はnode->getBoundingBox()となり、CCDirector::sharedDirector()はDirector::getInstance()となった。
さらにgetterはconst関数として宣言され、setterは引数をconstな参照で受け付けるようになっている。特にsetterの変更のおかげで、constで定義したデータを渡すのに四苦八苦する事はなくなるだろう。
◆関数ポインタとラムダ式
コールバックを多用するゲーム開発において、cocos2d-xの関数ポインタは不満の多いものであった。バージョン3.0からはC++11を標準としたことで、std::functionそしてラムダ式が使えるようになっている。もっともiOSならばObjective-Cのblocks、AndroidであればJavaの匿名クラスがあったわけで、ようやくといった感がある。
ともあれこれで、「ボタンを押したらシーンを遷移する」程度の処理のために関数を追加する必要はなくなった。
<例:ボタンを押すとシーンを遷移する>
URL:https://gist.github.com/kobayashi-poppin-games/8951732
◆コンテナクラス
Objective-Cでは配列はNSArray、ハッシュはNSDictionaryクラスを使用する。cocos2d-xではこれを踏襲しCCArrayとCCDictionaryという独自クラスが使われていたのだが、その実装はお世辞にも高機能とは言えないものであった。
cocos2d-x バージョン3.0ではテンプレートを使った、より「C++らしい」配列とハッシュが用意されている。cocos2d::Mapとcocos2d::Vectorがそうだ。CCArrayやCCDictionaryと同じく、これらのコンテナへ入れたObject型のインスタンスはretainされる。
cocos2d::Mapとcocos2d::Vectorは、標準のコンテナクラス同様、イテレータを提供する。C++11のautoキーワードによる型推論と組み合わせる事で、ループ処理などは非常に簡潔に記述できる。例えば子ノードすべてのタグを表示するならば以下のようになる。
<例:子ノードのすべてのタグを表示>
URL:https://gist.github.com/kobayashi-poppin-games/8952289
さらにSTLとラムダ式を組み合わせれば、例えば「x座標が100より大きい子ノードを探す」などの多少複雑な処理も、以下のように容易に記述できる。
<例:x座標が100より大きい子ノードを探す>
URL:https://gist.github.com/kobayashi-poppin-games/8952301
残念なのはbeta2現在、[]オペレータによるアクセスと、統一初期化構文(std::initializer_list)が使えないことであろうか。
<例:[]オペレータが使えない>
URL:https://gist.github.com/kobayashi-poppin-games/8952310
<統一初期化構文は使えない>
URL:https://gist.github.com/kobayashi-poppin-games/8952311
◆文字列のあつかいとValueクラス
文字列についてはCCStringクラスがDeprecatedとなり、代わりに全面的にstd::stringが採用されている。Sprite::create等のメソッドにおけるファイル名指定も「const std::string&」が標準の引数になっている。文字列のフォーマットに便利だったCCString::createWithFormatは、代わりにStringUtils::format関数が用意された。
コンテナと文字列の扱いの変化の他に、値を保持するためのcocos2d::Valueクラスが実装された。これはバージョン2系におけるCCBoolやCCFloatを置き換えるもので、Valueクラス一人で数値や文字列、さらにstd::mapとstd::vectorで出来たValue自体の配列やハッシュを保持できる。Value::NULLによってヌルも表現できるため、JSONデータの保持等にも便利だろう。
ただし、cocos2d::Valueはcocos2d::Objectを継承していない。cocos2d::Mapとcocos2d::Vectorはcocos2d::Object型のポインタ(つまりretain可能なもの)のみを受け付けるため、これらを組み合わせる事はできない。現状、cocos2d::Valueクラスはstd::vectorやstd::mapと共に使うことになる。
◆レンダラーの変更、グローバルZオーダーの導入
cocos2d-xでは、すべての描画はNodeクラスのツリー構造として表現されている。バージョン2系ではこのツリーの親子関係を超えて描画順を変更する事は、基本的にはできなかった。
バージョン3.0ではグローバルZオーダーが導入された。ノードにグローバルZオーダーを指定する事で、描画順をノードツリーと独立して指定できる。このため、「エフェクトの再生が他のノードに隠れないように、最上位のレイヤーで実行したい」といった要求も簡単に実現できるようになった。これまでのノードツリーを基準としたZオーダーも、ローカルZオーダーとして残っているので安心して欲しい。
この他にも多数の機能改善と、性能面の向上が予定されており、バージョン3.0でも特に注目度の高いフィーチャーと言えるだろう。
◆新しいイベントディスパッチャー
バージョン2系では、タッチイベントの処理優先度は見た目と一致していなかった。このためcocos2d-xに慣れたエンジニアでも、複雑な画面の構築は困難であった。
バージョン3.0ではレンダリング順にタッチ判定の処理が行われるため、タッチ優先度を外見と別管理する必要がなくなった。また、タッチイベントに限らずイベント処理はイベントリスナーとして抽象化されており、EventDispatcherへ追加できる仕組みになっている。これらイベントリスナーもstd::functionをコールバックとして受け付けるため、ラムダ式を使用できる。例えばラベルにタッチ判定を追加する処理の大枠は以下のようになる。
<例:ラベルにタッチ判定を追加する処理>
URL:https://gist.github.com/kobayashi-poppin-games/8952315
◆ラベルの改善
これまでTrueTypeフォントを使ったラベルの実装はプラットホーム別であり、iOS6系とiOS7系とAndroidでそれぞれ微妙に描画結果が違う、などの問題があった。またAndroidにおけるTrueTypeフォントのレンダリングはJavaのコードとして実装されており、オーバーヘッドが大きかった。
バージョン3.0からはfreetypeライブラリを用いたレンダリングに統一され、プラットホームごとの描画結果が同じになった。もちろんバージョン2系から導入されたシャドウとストローク(縁取り)も利用できる…はずなのだが、beta2ではiOS7上でストロークの色が正常に表示されないバグがあるようだ。iOS6系では正常に表示された。
◆多くの改善が加えられた新バージョン、移行のポイントは?
数々の改善・新機能が加えられたバージョン3.0だが、これまでバージョン2系列で開発してきたコードの移植は容易ではないだろう。大半のクラスはDeprecated扱いでまだ残っているとは言え、周辺ライブラリの対応まで含めると、かなりの修正が必要になるはずだ。またC++らしさが増した事で、C++に不慣れなエンジニアは、テンプレートやメモリ管理について学び直す必要があるかもしれない。
だがこれまでに述べた通り、バージョン3.0では一貫性を持った直感的なコーディングが可能となっており、関数定義等もよりロバストである。beta2は既に開発に利用できるレベルにあり、今後正式リリースまでにAPIレベルでの致命的な非互換がうまれる可能性も低い。今回紹介できなかったが、CocoStudioなどツール類の拡充もバージョン3.0を中心に行われるであろう事を考えれば、新規のプロジェクトでは旧バージョンを選択する理由はほとんどないだろう。ポッピンゲームズジャパンでも、バージョン3.0を積極的に採用する方針だ。
◆次回予告
次回はCocoStudioを使ったグラフィカルなゲーム開発と、cocos2d-xで使えるC++以外の言語の例として、JavaScriptについて紹介したいと思う。
<著者>
ポッピンゲームズジャパン株式会社
エンジニア統括 小林 敬介
<ポッピンゲームズジャパンについて>
2012年7月に設立の独立系のゲームデベロッパー。「ネイティブ」「高グラフィック」「グローバル」をテーマに、北米・アジアをメインターゲットとしてオンラインゲームを開発しています。自社IPの代表作に、ピーターラビットガーデン(200万DL)、アリスの不思議なティーパーティ(100万DL)。
ポッピンではエンジニア積極採用中です!cocos2d-x、WebSocket、AmazonWebServiceなど新しい技術にチャレンジしたいエンジニアの方、ぜひご応募下さい。
http://poppin-games-japan.com/recruit/career/
会社情報
- 会社名
- ポッピンゲームズジャパン株式会社
- 設立
- 2012年7月
- 代表者
- 代表取締役CEO 谷口 祐一郎
- 決算期
- 6月