5.1さらうどん

@giginetの技術ブログ。ゲーム開発、iOS開発、その他いろいろ

cocos2d-xでPhysicsWorldを使ったときのScene Graphの挙動にハマった話

f:id:gigi-net:20140710105133p:plain

ちょっと物理エンジンを使う必要があって、cocos2d-x 3.0から本体に取り込まれた物理エンジンを使ってみることにしました。

ところが、以前一度使ったことがあったのですが、バグっぽい挙動で数時間ハマって困った。

あれこれ調べてみて無事に解決したのでブログに記しておきます。

以下、3.1環境を想定して読んでください。

問題

今回起こった問題は、「剛体を付けた子ノードが親ノードに追従しない」という問題。

3.x系になってから一度物理エンジンは使ったことがあるけど、スクロール無しで完結するゲームだったので特に困らなかった。

Scene Graphが維持されないという問題は、画面スクロールがあるようなゲームを作るときに大変困る問題だと思う。

問題を検証するために、3.1環境で新規プロジェクトを作成し、HelloWorldSceneを書き換えてみた。

物理エンジンの初期化

Scene* HelloWorld::createScene()
{
    // 物理エンジンを有効にしたシーンを作成する
    auto scene = Scene::createWithPhysics();
    
    // 物理空間を取り出す
    auto world = scene->getPhysicsWorld();
    
    // 重力を設定する
    world->setGravity(Vec2(0, -1));
    
    // デバッグモードを有効化する
    world->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
    
    auto layer = HelloWorld::create();
    
    scene->addChild(layer);
    
    return scene;
}

まず、createScene()メソッドを書き換えて、物理エンジンを有効化します。

2.xと違い、3.xからはPhysicsWorldがSceneに取り込まれたので、Sceneにくっつけてあげます。

ちなみに、公式のドキュメントがあるんですが、3.0α版の時点で書かれたモノのようで、公式ドキュメントなのに、最新版の環境でドキュメントを写すとビルドすら通らないという割と酷い代物なのでご注意を!おそらく最新環境では上記コードが正しいです。

Physics | Cocos2d-x

問題:子ノードが親ノードに追従しない

   
    // add "HelloWorld" splash screen"
    auto sprite = Sprite::create("HelloWorld.png");
   
    // Spriteを剛体にする
    auto body = PhysicsBody::createBox(sprite->getContentSize());

    // ここをコメントアウトすると物理エンジン無しの挙動を簡単にシミュレートできる
    sprite->setPhysicsBody(body);
    
    // 重力を無効化する
    body->setGravityEnable(false);
    
    // 適当なラッパー用のレイヤーを用意する(わかりやすいように色を付けている)
    auto node = LayerColor::create(Color4B::BLUE);
    this->addChild(node);
    
    // 検証のためにラッパーがゆっくり上に上がるようにする
    node->runAction(RepeatForever::create(MoveBy::create(30, Vec2(0, 5000))));
    
    // position the sprite on the center of the screen
    sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
    
    // Spriteをシーンに直接追加せず、ラッパーに追加する
    node->addChild(sprite, 0);
    

こういうコードを書くと、nodeが上に上がる際に、それの子ノードであるspriteが追従して一緒に上がる挙動になるかと思います。

物理エンジン無し(3.1)

f:id:gigi-net:20140710103828p:plain

青いレイヤーがActionで上に移動していき、その子ノードのSpriteが一緒に追従して上っていく。想定された挙動。

sprite->setPhysicsBodyの行をコメントアウトするだけ。

物理エンジンあり(3.1)

f:id:gigi-net:20140710103708p:plain

同じ挙動をして欲しいのに、なぜか親ノードだけが上がっていき、Spriteは動かない。バグっぽい。

ちなみに、ラッパーを作らずに、thisを直接上に動かしても再現するけど、見やすさのためこのような実装にした。

明らかにバグっぽい

どうやら、PhysicsBodyをセットしたノードは親ノードの動きに追従してくれないみたい。

酷い挙動だ。

親ノードに剛体を付けたりしてみたけれど、それでもダメ。

マニアックな問題ではなく、物理エンジンとスクロールを併用しようとすると結構ハマる問題では。

例えば、『AngryBird』や、『LIMBO』のような物理エンジンを載せたプラットフォームアクション的なよくあるゲームを作るだけでも困る。

解決するには

当初は、自分で中のコードを弄って解決していたのですが、3日前(2014/7/7)に出たばかりの3.2rc0のCHANGELOGを見ていたらこんな記述が

   [FIX]           Physics integration: child node can move with its father

cocos2d-x/CHANGELOG at e1b29a8ef61248ec047b17be921e031d0d637904 · cocos2d/cocos2d-x

どうやら3日前に出たバージョンでは直っていたようだ。

3.2rc0

f:id:gigi-net:20140710104753p:plain

3.2rc0に上げたところ無事に動く。よかった!

がんばってdiffを追ってみたところ、2週間前のこのPull Requestで修正されていたようだ。

closed #5614: add transform support for physics by boyu0 · Pull Request #7234 · cocos2d/cocos2d-x

このPR出している人、物理エンジンガチ勢みたいな人で、履歴を見てみると物理エンジン周りに大量のPRを送っている。ありがたい限りである。

テストアプリ

3.2rc0から、付属しているcpp-testアプリに「Physics Transform Test」というテストが追加されていて、そこで挙動を確認できる。

このように、移動だけでなく、親ノードに対して回転や拡縮を行っても子ノードが追従して動くようになった。嬉しい。

f:id:gigi-net:20140710105133p:plain

まとめ

cocos2d-xヤバい。数週間に1回バージョンアップする上に、1回のバージョンアップで大量の変更が取り込まれ、数日前に動かなかった物が今日は動く、みたいなことがよく起きる。

今回発見できた問題はたまたま氷山の一角で、この手のバグは大量にありそうなのでご注意を!

よく使うディレクトリに瞬時にautojumpするAlfred Workflow作った

autojumpが便利

autojumpというCUIユーティリティがめっちゃ便利で良く愛用しています。

zsh使いなら効率改善のため知っておきたいAUTOJUMP - Glide Note - グライドノート

autojumpはある文字列から、それを含む一番よく使うディレクトリに自動的に移動してくれる優れもの

例えば

$ j D

などと入力すると、~/Desktopなどに一発で移動できます。

GUIで使いたい

他にjoというコマンドがあって、それを使うとGUIディレクトリを開くこともできるけど、いちいち黒い画面を立ち上げなければならないので、上手い具合にGUIでも使いたかった。

Alfred Workflow作った

Alfred App - Productivity App for Mac OS X

Alfred2の有償版には"Workflow"という仕組みがあり、自分で検索用のスクリプトを作ることができます。 というわけで、Alfredからautojumpを叩く奴を作ってみた。

giginet/alfred-autojump-workflow

基本の使い方はAlfredを立ち上げて「J <キーワード>」と入力するだけでOK!

また、候補がみつからなかったときは、データベースの上位にあるディレクトリの一覧を表示してくれる。ディレクトリ名がうろ覚えでも簡単にアクセスできてベンリベンリ。

Workflow内にautojumpを含めているので、shellでautojumpを導入していなくても使えるはず・・・・・・。(未確認)

CUI版を使っている人は、同じデータベースを共有しているので、今まで学習させた頻度データがそのまま使えます。逆にWorkflowからautojumpしても、CUIで使うのと同様に利用頻度の更新も行われるため、CUI版を使わなくても利用できるはず。

導入方法

  1. Afred2をインストールする
  2. Alfred PowerPackを買う
  3. autojump.alfredworkflowをダウンロードする
  4. ダブルクリックでインストールする

どうぞご利用ください。

Alfred Workflowの作り方

初めて作ったので見よう見まねでやってみました。

基本はスクリプトを書いて、標準出力を順次受け渡していくだけ。 普通にShellスクリプトを書いて自由に実行できる。Python, Perl, Ruby, PHPなどのスクリプトを実行することもできるので好きな言語で書けます。 一覧表示をしたり、特殊な表示方法は、決まったフォーマットのXMLで出力することで整形してくれます。

公式ではPHPスクリプトが多くて、Alfred向けのフォーマットに出力してくれるライブラリが充実している感じ。要はXMLを吐けばいいので何でも書けます。僕はPythonで書いた。

autojump.alfredworkflowは、ScriptFilterで候補を表示し、Run Scriptでopenしてるだけの簡単な実装

f:id:gigi-net:20140626113240j:plain

資料はあんまり多くないですが、公式のフォーラムや、他の人が作ったWorkflowを参考にすれば、割と自由にいろいろ作れると思います。

Workflows - Alfred v2 Support

zenorocha/alfred-workflows

究極のレトロゲーコンソール『RetroN 5』ファーストインプレッション

f:id:gigi-net:20140610145614j:plain

究極のレトロゲーム互換機、『RetroN5』がついに届きました!プレオーダーしてから9ヶ月。長かった!

RetroN 5 |

試しに遊んでみたら、想像以上に良いハードウェアだったので、是非皆様にもこの素晴らしさをお伝えしたいと思ったので、記事にすることにしました。

RetroN 5とは

5スロット9機種互換レトロゲーム機 RetroN 5、ファミコン / NES / SFC / MD/ GBA でステートセーブ可能 - Engadget Japanese

超高機能なレトロゲーコンソールです。

主な特徴は以下の通り。

このように、コンセプト段階から機能があまりにも豊富で、期待度が高いガジェットでした。

購入まで

昨年の3月ぐらいに商品化が決まってから、Pre Order開始まで情報を追い続けていました。

昨年の9月になって、ようやっとAmazon.comでのPre Orderが開始したので速攻で予約。国外配送も可能とのこと。 価格は日本への送料を含め$98ほど。

Amazon.com: Hyperkin RetroN 5 Retro Video Gaming System - Gray: Video Games

当初は昨年11月に発送予定だったのですが、今年1月に伸び、さらに延期。

そのままずっと音沙汰がなかったのですが、先日になってようやっと配送されました。 当初、昨年の夏ローンチ予定だったのに待ち続けること1年以上!長かった。

開封の儀

注文してから延期を重ね9ヶ月、ようやっと昨日届きました。うおおお。

f:id:gigi-net:20140609085635j:plain

開けてみる。海外製なので箱が潰れてる。雑だ・・・・・・。

f:id:gigi-net:20140609183617j:plain

micro-USBや、HDMI、日本向けのACアダプタなども最初から同梱されているので、買ってすぐに使えます。低価格なのに嬉しい。

実際に遊んでみる

上から見た図。上(奥)から順番にMD(Genesis)、SFCNES(北米版ファミコン)、FCの4スロット。手前にはGB/GBAのスロットが。

f:id:gigi-net:20140609194627j:plain

マスターシステムで遊ぶには専用の端子が必要らしい。

f:id:gigi-net:20140609190704j:plain

とりあえず手持ちのソフト何本かで検証。

起動後のメニュー画面。設定でスキップさせることもできます。

f:id:gigi-net:20140610145932j:plain

まずはファミコン。個人的神ゲーの『ランパート』。

f:id:gigi-net:20140609191410j:plain

次にGBA。『チューチューロケット』。

f:id:gigi-net:20140609192205j:plain

一応メジャーなのも遊んでおくかー、と思って『ポケットモンスター サファイア』を起動。問題なく遊べますねー。素晴らしい。

f:id:gigi-net:20140609192340j:plain

最後にメガドライブ。『サンダーフォースⅣ』を起動。メガドライブだけ、やたらと端子が堅くて、刺すのも抜くのも一仕事。壊したのかと思ってビビる。

f:id:gigi-net:20140609192615j:plain

さすがにHDMI出力なのでどのゲームもめっちゃ綺麗。大画面で遊んでも全く問題ありません。

GBとSFCはパッと出てこなかったので検証していません。SFCのソフトどこかにあったはずなんだけどなぁー。

スターフォックス』や『スーパーマリオRPG』といった、特殊チップを積んだゲームにも、対応している様子。実機を持っていなかったので検証できなかったのですが、今度試してみます。

唯一残念な点として、5つあるスロットのうち、2ヶ所以上の端子にカートリッジがあると、エラーが出て起動しないこと。 複数さして置いてメニュー画面で選択できると嬉しかったんですが・・・・・・。

コントローラー

お次はコントローラーの話。

付属のワイヤレスBluetoothコントローラーがあるので、とりあえず遊ぶだけならすぐに遊べます。

f:id:gigi-net:20140609190202j:plain

しかし、このコントローラー、お世辞にもあんまり使いやすくなくて微妙な感じなのですが、外部のBluetoothコントローラーで自由に拡張可能らしい。

オマケにNESSFC、MDのコントローラーポートが計2つずつ。合計6つ。実機のコントローラーも使えます。

f:id:gigi-net:20140609185801j:plain

繋いでみた。ご存じ、日本版のFCはコントローラーの取り外しができないので、このポートはおそらくNES(北米版ファミコン)向けかと。さすがに手持ちにコントローラーがなかったので検証できず。

f:id:gigi-net:20140609192814j:plain

コントローラーは最大で5台まで接続可能で、SFCのマルチタップを使うようなゲームにも完全対応。これだけで『ボンバーマン』などの5人プレイが遊べます。

さらに凄いことに、全てのコントローラーを相互に利用可能。ファミコンのゲームをメガドラのコントローラーで遊んだり、自由自在。至れり尽くせりですね。

キーマッピングも自由自在で、プリセット登録まで対応。 余ったボタンにステートセーブや早送りなどのマクロを割り当てておくこともできます。

セーブデータとステートセーブ

素晴らしいと思ったのがセーブデータの仕様。まず、カートリッジにセーブデータがあるソフトを初回起動すると、自動的にセーブデータがSDカードにインポートされる。 さらにSDカードに保存したセーブデータとカートリッジのデータをいつでも自由に読み書きできます。

f:id:gigi-net:20140609192305j:plain

そして、全ゲームでステートセーブ/ロードが可能。スロットも複数箇所あって、前述の通り、マクロで一発呼び出し。

神設定だと思ったのが、自動ステートセーブ&ロード。設定しておくと、次回起動時に自動的に前回終了したゲームが読み込まれ、つづきから遊べます。もちろんソフトごとに保存される。

各種設定

設定もムダに充実。グラフィックの表示モードを切り替えたり、オーディオ周りの設定をしたり・・・・・・。

f:id:gigi-net:20140609195210j:plain

リージョンも設定できるので、海外製のソフトも遊べます。

その他の機能

まだちゃんと試せてないけど、チートコード機能。チートコードの定義ファイルをSDカードに突っ込んでおくと、ゲーム中、いつでもチートコードが呼び出せます。

RetroN 5 | Cheats

細かい機能だけど、スクリーンショットを撮ってSDカードに保存することも可能。

まとめ

想像以上に究極のコンソールでした。これは絶対に買い!

豊富な機能があるのはもちろん、全ての機能が全ハードで同じインターフェイスで扱える作り込みが素晴らしい。レトロゲー遊びたい人の決定版ですね。 価格を考えても非常にお買い得。

案の定、海外では売り切れ続出のようで、Amazon.comでは現在価格が$230ぐらいまで高騰してます。

Amazon.com: Buying Choices: Hyperkin RetroN 5 Retro Video Gaming System - Gray

買いたい方は、在庫が安定するまで待つしかないんじゃないかなあ・・・・・・。他に買えるところがあれば教えてください。