2011/12/25

coco2d Advent Calendar 2011 24日目: オーバートップレイヤーのすすめ

あいかわらず後からの投稿になっちゃいますが、めげずにcocos2d Advent Calendar投稿します。
 今回は、以前さいたまiPhone勉強会で発表した内容からのピックアップで、オーバートップレイヤーというものを実装してみたという例のご紹介です。

<中級編>オーバートップレイヤーのすすめ

●まえがき
 ゲームでは、よく画面を覆う枠があったり、画面上部に体力やスコア表示などが分けて表示されていたりするような画面配置がありますよね。たとえば、以下のような感じです。
 Ysなどの往年の国産PCゲームでは、画面を覆う枠があり枠内がスクロールするゲーム画面。枠の下には体力などのパラメータ表示となっていました。たとえばこんな感じで検索するとヒットしますよ。
 また、ファミコンのゲームではよく画面を上下に区切って画面上部にアイテムやパラメータ表示をして、画面下部はスクロールするゲーム画面として使用するようなものもメジャーでした。たとえばグーニーズとか。ほら検索すると画面がヒットしますよ。

 こんな感じの表示を行う場合に、CCLayerを2つ用意して、1つは枠や画面上部のパラメータ表示用に使用し、もう1つはゲーム画面として使用するように作ると思います。しかし、ゲームの進行で別のマップへ移ったりする際にフェードアウト・フェードインして画面切り替えを行おうとするとcocos2dで普通に推奨されている方法で組むと、パラメータ表示用も含めてフェードがかかってしまい、あまりかっこ良く有りません。ちなみに、このcocos2dで推奨されている組み方はCCSceneにCCLayerを2つ子供にして別のCCSceneへ切り替えるというものです。
 そこで、今回ご紹介する方法が出てくるわけです。


●オーバートップレイヤーの仕組み

 仕組みはこんな感じとなります。通常cocos2dで用意されている画面遷移関数はCCSceneを入れ替えるものですが、この方法ではCCScene自体は基本的に入れ替わらず、ゲーム画面として使用しているCCLayerだけが入れ替わるという構造になります。もちろん、そんな便利なメソッドは用意されていないので、レイヤー入れ替え部分は自作しなければなりません。

 CCSceneの定義自体はこんな感じとなります。
+(MainScene*)sceneWithLayerTop:(CCLayer*)layerTop
           layerBelow:(CCLayer*)layerBelow
{
  MainScene *scene = [MainScene node];

  layerTop.tag = kLayerTop;
  layerBelow.tag = kLayerBelow;

  [scene addChild:layerBelow z:0];
  [scene addChild:layerTop z:2];

  return scene;
}


 で、画面遷移用にとりあえずこの2つのメソッドを用意してみました。メソッドの中のコードはサンプルコードを参照してください。transitionFadeWithLayerは黒フェードを用いてレイヤーの入れ替えを行うものです。transitionFlowerWithLayerはオマケ的なものですが、花で画面が埋め尽くされて花が画面上から去るとレイヤーが入れ替わっているというものです。
- (BOOL)transitionFadeWithLayer:(CCLayer*)layer
           duration:(ccTime)d;

- (BOOL)transitionFlowerWithLayer:(CCLayer*)layer
           duration:(ccTime)d;



●実装の注意点
 実装にあたって、以下の部分に注意しました。
・関係するレイヤーのタッチイベントの無効化だけでは余り効果を発揮しなかったので、画面遷移の重複が起きないように注意した。
・トランジション中フラグを用意して、トランジションメソッドが複数動作しないように制御した。
 と、こんな感じですが、荒削りなので実際に使用するにはもう少し改善の余地はありそうです。でも、夢が広がると思います。


●夢がひろがりんぐ
 もともとオーバートップレイヤーが欲しいなと思ったのは、GameCenterでのアチーブメント解除表示を行う際に画面上部などにアチーブメント情報を表示し始めたとしても、その後すぐに画面遷移が行われてしまった場合にアチーブメント表示が消えてしまうのをなんとかしたいと思ったところから発想しました。もちろん、ネットをググれば同様の問題の対処としてcocos2dのCCSpriteオブジェクトなどをcocos2d外のものに適用して表示させる方法があったりしましたが、なんだかスマートじゃないなと思っていたのです。どうせなら表示はすべてcocos2dの中で完結させたいと。
 オーバートップレイヤーがうまく動いてしまえば、往年のゲーム的な画面表示が簡単に行えるので、これはいいんじゃないでしょうか。おすすめですよ。

 ではでは、今回はこのへんで。

0 件のコメント:

コメントを投稿