Cocos2d-xで3Dプログラミング!?

こんにちは。野口です。
業務アプリプログラマーがCocos2d-xでゲームを作るシリーズをお届けします。

前回、Cocos2d-x v3.0正式リリース記念ということで記事を書かせていただいたわけですが、その舌の根も乾かぬうちに(正式リリースから2週間ほど)、実はv3.1alphaが発表されていたわけです。
この記事を書いている6月26日現在では、なんとv3.1.1として正式にリリースされています。

いやはや、このスピードとパワフルさにはただただ舌を巻くばかりです。

そんなv3.1の目玉機能はは、ズバリ3D!!
これにはビックリです。
元々Cocos2d-xは2dプログラミングしか出来ないわけではなく、OpenGL ES 2.0系のシェーダプログラミングをサポートしており、ちょっとした3D(例えば、Wizardryのような1人称視点で進んでいくダンジョンのような)ものであれば、割と簡単に作れたりはしました。
作れはしましたが・・・。
Cocos2d-xと言えば、その名の通り2dゲームエンジンとして最速最強を目指して突き進んでいくのだと思っていたので意外でした。

さて、それはそれとしてCocos2d-x v3.1alphaからv3.1.1に至るまでのCHANGELOGから新機能を抜き出して紹介していきたいと思います。

  • 3Dモデル描画用のノードであるSprite3Dを追加しました。
  • スマートポインタをサポートするRefPtrが追加されました。
  • Labelはauto-cullingをサポートするようになりました。
    ※auto-cullingというのは、画面の外側にはみ出ている部分の描画をカットすることで実行速度をアップさせる処理を自動で行ってくれます。
  • Kazmath、CCGeometry、CCAffineでの統合された新しいMathライブラリを提供します。
  • カスタムシェーダを利用したSprite描画のサンプルコードを追加しました。
  • GLProgramをより簡単に行えるための新しいクラスGLProgramStateを追加しました。
  • Eclipse project用にC++のテンプレートを追加しました。
  • UIにNavigation(スクロールバー)を追加しました。
  • UIにビデオ再生用のウィジェットを追加しました。
  • Visual Studio 2013に対応しました。

RefPtrとか嬉しいですが、正直、ちょっと地味? な印象は拭えませんね。
やはり大きく目を引くのはSprite3Dでしょう。
では早速、Sprite3Dとはどういうものなのか、ご紹介させていただきます。

今回のSprite3Dに限らずですがCocos2d-xで新しい機能が追加されたときに、それがどういったもので、どのような使い方をするのか?
一番、確実で手っ取り早いと思われる方法がCocos2d-xのテストコードを読むことだと思います。
また、読むだけではなくて、実際にビルドして動かしてみるとより理解が早まるのでおすすめです。

詳しくは↓こちら
cpp-tests(http://www.cocos2d-x.org/wiki/How_to_run_cpp-tests_on_iOS)

・ Sprite3Dの使い方

    // スプライトの生成
    auto sprite = Sprite3D::create("Sprite3DTest/boss1.obj");
    sprite->setTexture("Sprite3DTest/boss.png");
    addChild(sprite);
    
    // 画面の中央に配置
    auto winSize = Director::getInstance()->getWinSize();
    sprite->setPosition(Vec2(winSize.x / 2, winSize.y / 2));

取り敢えず、3Dモデルを読み込んで配置するだけならこれだけで出来ます。
というか、Sprite3Dというのは3Dモデルファイルを読み込むためのものだったんですねっ!!
読み込めるのは、Wavefront OBJ形式のようです。
「Sprite3DTest/boss1.obj」のことですね。
このファイルはcpp-testsのResourceにあるものを
そのまま使わせてもらっています。

因みに、描画位置を指定している
「sprite->setPosition(Vec2(winSize.x, winSize.y));」
Vec2という見慣れないClassが登場していますが、
実はコレSprite3D用というわけではないのです。
以前まで使っていたPointがVec2に変更になったようです。
ビックリですねっ!! 変更する必要があったのかイマイチ分かりませんが。

それはさておき、このSprite3Dですが使い方は至って簡単。
Spriteクラスと同じような感じで使えるように作られています。

・ Sprite3Dでアニメーション

    auto rotate = RotateBy::create(3, 360);
    auto move   = RotateBy::create(3, 360);
    auto seq    = Sequence::create(rotate, move, NULL);
    sprite->runAction(RepeatForever::create(seq));

・ イベントの登録

    // 色々と書いてありますが、普通のSpriteにTouchイベントを登録するのと同じです.
    auto listener = EventListenerTouchOneByOne::create();
    listener->setSwallowTouches(true);
    listener->onTouchBegan = [](Touch* touch, Event* event) {
        auto target = static_cast<Sprite3D*>(event->getCurrentTarget());
        Vec2 locationInNode = target->convertToNodeSpace(touch->getLocation());
        Size size = target->getContentSize();
        Rect rect = Rect(0, 0, size.width, size.height);
        if (rect.containsPoint(locationInNode))
        {
            log("touch");
            return true;
        }
        return false;
    };
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, sprite);

と、このような具合です。
Spriteクラスと同じように使えるということがご理解いただけたかと思います。

・ さいごに

Cocos2d-xで3D・・・。如何でしたでしょうか?
3Dモデルファイルは別途用意する必要がありますが、簡単に読み込めて通常のSpriteと同じように動かせるということなので、
これまでの2Dゲームのアクセントとして3Dモデルを取り込むというような用途がパッと思い浮かぶのではないでしょうか?

コメントを残す

メールアドレスが公開されることはありません。

ABOUTこの記事をかいた人

アバター

僕と契約してアーティストになってよ。 普段はJavaやPHPで業務Webアプリばっかり作っています。 安西先生、Rubyで仕事がしたいです・・・。