だいたい47度

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

PageTop

Box2Dを知るためLearning Cocos2Dを読む(6)Part IV Physic Engines - 2

cocos2dの物理エンジン周りの勉強&cocos2dの復習のため、Learning Cocos2Dを読んだメモを残していきます。

全5部17章構成で、今回は4部の12-13章と5部の16章を読みます。12章では前回学んだ物理エンジンゲームを進化させ、13章ではChipmunkを使って新しいステージを一つ作ります。「Part V Particle Systems, Game Center, and Performance」は14-17章からなりますが、14章のパーティクルや15章のゲームセンターは日本語の書籍も充実しているし飛ばします。ただ16章のパフォーマンスについては知っておきたいので読んでおきます。

【過去】
Learn Cocos2Dを手にとった理由
Part I Getting Started with Cocos2D
Part II More Enemies and More Fun
Part III From Level to Game
Part IV Physic Engines-1

今回みていて学べたのは、すべての物体をバカ正直に正確な形で定義しなくていいことです。例えば、ドリルを持った敵ロボットを作りますが、四角の身体に円の車輪をつけ、ドリルは三角形のセンサを左右につけるだけです。確かに微妙な凸凹などを表現しても意味無いですね。なるほどなー。

Chapter 12 Advanced Game Physics: Even Better than the Real Thing
まずトロッコに主人公を乗せます。主人公は複数のパーツからなっていて、トロッコの動きにあわせてリアルに動きます。パーツはそれぞれrevolute jointやprismatic jointでつながっており、enableLimitで動作範囲を絞っています。

・パーツを組み合わせるときは、回転を考慮するため、GetWorldPointを使うべきとのこと。AにBを追加する場合のBの位置合わせは、A.GetPosition().x + offset.xなどを使うのではなく、A->GetWorldPoint(offset)を使うのですね。

・パーツ接続点の決定は画像編集ツールを使えばいいけど、Mekanimo、LevelSVGなどのツールを使うとかなり楽になるとのこと。動作テストもできコードも生成してくれるらしいですが、日曜プログラマには高い……。TexturePackerならまだ手が出るかな。

・パーツはトロッコ等と衝突してはいけないので、fixtureDefのfilteringで幾つか設定をします。ここは珍しく説明が適当で、マニュアル読んだ方がいいです。マニュアルは必要十分な例が挙がっていてわかりやすいです。

・パーツのSpriteはbatchNodeに突っ込みましょう。layerクラスでキャラクタクラスをallocした後に、layerクラスが管理するbatchNodeにaddするような形です。

ある程度ゲームサイズが大きくなっていくと、updateが起こる秒数にブレが出てきて、updateごとに1回Stepを呼ぶ単純なやり方だと挙動がおかしくなっていきます。そこで以下のように、各updateに複数Stepの処理もさせてやり、また時間が飛びすぎた時の対応を書いてやるといいそうです。
static double UPDATE_INTERVAL = 1.0f/60.0f;
static double MAX_CYCLES_PER_FRAME = 5;
static double timeAccumulator = dt;

if (timeAccumulator > MAX_CYCLES_PER_FRAME * UPDATE_INTERVAL)
timeAccumulator = UPDATE_INTERVAL;//飛びすぎた時の処理

while (timeAccumulator >= UPDATE_INTERVAL) {
timeAccumulator -= UPDATE_INTERVAL;
world->Step(UPDATE_INTERVAL, velocityIterations, positionIterations);
}

ボスの敵ロボットは上述のように簡単に作ります。体当たりで吹っ飛ばせるように、densityは低くする一方、ひっくり返らないようにSetAngularDampling(1000)として回転への耐性をあげています。ここは切り離して制御できるんですね。

最後に、ボス戦開始時の前に演出を入れる方法を説明して終わりです。ボス戦の開始位置にセンサを設置、updateメソッドで感知することで演出を開始します。演出の開始時に、主人公に対してsetMotorSpeed:0とSetLinearVelocity(b2Vec2(0,0))を実行して動作を止めます。前回記述した通り、SetLinearVelocityを使うと動きがおかしくなるのであまり使わないほうがいいのですが、動きを全て止めるなどのときは良いよとのことです。あとはCCActionで適当に。

Chapter 13 The Chipmunk Physics Engine (No Alvin Required)
Box2DからChipmunkに頭を切り替えてステージ5を実装します。

Box2DとChipmunkの比較から。worldがspaceだったりと言葉は違うのですが基本的な流れは一緒なんですね。違いとしては、Cで書かれているかC++で書かれているか、位置制御をポイントでやるかメーターでやるか、などが挙げられるようです。また、Chipmunkの方が簡潔な関数が多いため一つ一つのプログラム記述量は少ないけれど、Box2Dよりもjointなどの既製品が少ないので全体的な記述量では多くなることもあるようです。あと、Chipmunkだとオブジェクトに直接速度を渡してもキレイに動くらしいですが、一方で偶に物体同士が突き抜けてしまったりもするそうです。どうも一長一短ですね。

さっそくspaceを作ってみます。Chipmunkはspaceをgridにわけ、違うgridにあるオブジェクトは衝突していないとみなすそうです。
cpInitChipmunk(); //Chipmunkの開始
space = cpSpaceNew();
space->gravity = ccp(0, -750); //重力 ポイントで指定
//第二引数はgridのサイズ、第三引数はgridの数
cpSpaceResizeStaticHash(space, 400, 200);
cpSpaceResizeActiveHash(space, 200, 200);

このあとはオブジェクトを作ったり、Spriteを載せたりして基礎を確認した後、ステージ5を実装していきます。衝突時の返り値の形がBox2Dとは異なったりする部分や、どんなJOINTがあるかなどを50ページくらいかけて説明してくれます。概ね空気は分かったので、残りは読み飛ばし。というかBox2Dでとりあえず何か作って遊びたくて気がそぞろになってしまい読めません……。

Chapter 16 Performance Optimization
iPhoneゲームを作る際、パフォーマンスが意外とネックになったりします。ちょっと凝った動作を作ってみたら実機テストをしてみるとカクカクだったりしてがっかりします。そうなると全体的に見直しが必要になったりして本当に面倒です。のでここはとても重要なのです。

まずSprite系で知ってたTIPs。CCSpriteBatchNodeを使いましょう。テクスチャアトラスには空きスペースがないようにしましょう。場合によっては小さな画像をテクスチャアトラスに登録し、拡大して使いましょう。FlipXやFlipYで作れる画像は片方だけ登録しましょう。spriteはlayerのinit時にallocしましょう。そして再利用できるSpriteは再利用しましょう。要らなくなった画像はキャッシュから消しましょう。なおこの辺については、cocos2dで作る iPhone&iPadゲームプログラミングも弾幕を詳しく説明してくれていて良いです。

Sprite系であまり知らなかったTIPs。Bit depthは小さくしましょう。PVR形式は圧縮したままメモリに載せられるので使えたら使いましょう(リアル調の絵や写真に有効)。gzipされているPVR.CCZ形式も有効。

蛇足ですが、Sprite系TIPsで書いてなかったけど、以前実験したとき有効だったものも書いておきます。spriteのpositionを取得して画面外だったらvisible=NOとするだけで処理速度が変わります。特に事情があってCCSpriteBatchNodeが一部spriteに使えないときはかなり変わります。

処理の時間が計測したい時はCCProfilingTimerが便利。Nameには適当に独自名をつける。
//timerをretain
CCProfilingTimer* timer = [CCProfiler timerWIthName:@"timer" andInstance:self];
//計測開始
CCProfilingBeginTimingBlock(timer);
//計測終了 時間を標準出力
CCProfilingEndTimingBlock(timer);

あとはXcode付属のInstrumentsについて幾らか書いてくれています。これはUser's guideを読むのが良さげですが、とりあえず取っ掛かりに。


ということで、読み終わりました。お疲れ様でした。次回、総括しておしまいです。


Learning Cocos2D: A Hands-On Guide to Building iOS Games with Cocos2D, Box2D, and ChipmunkLearning Cocos2D: A Hands-On Guide to Building iOS Games with Cocos2D, Box2D, and Chipmunk
(2011/07/07)
Rod Wenderlich, Ray Strougo

商品詳細を見る
関連記事
スポンサーサイト

PageTop

コメント


管理者にだけ表示を許可する
 

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。