プログラミングの魔物

エラー、バグ、仕様変更と戦うブログ

cocos2d ゲームの構成要素。複数のシーン

cocos2dで作るiPhone&iPadゲームプログラミング5章

今日もxcodeで。5章はゲームの構成要素

4章は小規模だったこともありひとつのクラスでなんでもやっていたが、大規模なゲーム開発では複数のクラスに分割して管理する方が効率的である。
そこで5章では横スクロールシューティングを作りながら複雑なゲームを開発するための構成要素を紹介する。

5.1複数のシーンの処理

画面遷移の時には以下のメソッドが呼び出される。各自、superを呼び出す必要があり、怠るとメモリリークが発生したり入力が受け取れなくなったりする。

-(void) onEnter  //ノードのinitが呼び出された直後に呼び出される。CGTransitionSceneを使う場合、遷移が始まった時に呼び出される
-(void) onEnterTransitionDidFinish  //onEnterの直後に呼び出される。CGTransitionSceneを使う場合、遷移が終わった時に呼び出される
-(void) onExit //ノードのdeallocメソッドが呼び出される直前、CGTransitionSceneを使う場合は遷移が終わった時に呼び出される

5.1.2NowLoading...

シーンを切り替える際には2つのシーンが同時にメモリ上に存在することになる。
重いシーン2つを切り替える際は、間に軽いシーン(NowLoading)をはさむといい。
同じシーンを使い回せばいいので、NowLoadingをいくつも作る必要はない。
※本の例だとLoadingSceneクラスは遷移に必要なすべてのシーンクラスを予め知っている必要があるけど、これだと再利用性がないのでenumのシーン番号の代わりにシーンのクラス型を登録できるクラスを作るとよさそうな気がする。
インスタンスの代わりにクラス型を登録するのはメモリ対策。
また、Nowloading画面も外部で定義できるように作っておけばLoadingSceneクラスを他のプロジェクトで使用する際に修正が必要なくなる。

とりあえず、その辺りを考慮しつつ移植していたら・・・
いざデバイスで動かそうとするとCould not launch 〜エラーで動かず、DerivedDataを削除してみたもののダメで、最終的にプロジェクトから作りなおしたら動いた。
更にプロジェクトから作り直すときも.hと.mをそのままプロジェクトに追加したらリンカエラーで動かなかったので、クラスごとにcocos2dのテンプレートから作成してやっとデバイス上で動作した。どうやらxcode4の仕様らしい。
http://d.hatena.ne.jp/J_ogawa/20120403/1333419277
※プロジェクトに追加する際、AddToTargetsにチェックが付いてなかった。

cocs2dでshareddispatcherがdeprecatedとでる
http://www.eui-jp.org/2012/07/cocs2d%E3%81%A7shareddispatcher%E3%81%8Cdeprecated%E3%81%A8%E3%81%A7%E3%82%8B/

replaceSceneのルール

ノードのinitメソッドでCCDirectorのreplaceSceneを呼び出さない

5.2複数レイヤの処理

MultiLayerSceneは他のレイヤから参照できるように半シングルトン。シーンが存在する間はメモリ上に確保される。
sceneを作る段階で複数のLayerをaddChildし、ノードタグにはあらかじめenumで定義された物を使って登録している。
※CGGeometryには交差、範囲内のポイント、等価を評価するための便利なメソッドがある。

5.3レベルを実装する最もよい方法

レベルを実装するにはレイヤとシーンどちらがよいか?
それぞれに利点がある。ゲームにおいての役割によって分ける。

  • シーン

レベルごとにシーン作成or共通のLevelSceneクラス
レベル内で発生するオブジェクトがクリア後に不要になる場合
インターフェースは最低限。アクションなど反射神経系

  • レイヤ

インターフェス複雑。オブジェクトの状態があまり変化しない。
部屋から部屋へと移動するアイテム探しやアドベンチャー
CCLayerMultiplex・・・複数のノードを追加して、アクティブノードをひとつ表示
CCLayerColor・・・レイヤの背景色を指定する時

5.4CCSpriteからのゲームオブジェクトのサブクラス化

キャラクタークラスはCCSpriteから派生するのではなくスプライトを持つ。
CCSpriteが元々備えている機能ではキャラクターを表すのに足りないものが多すぎる。例えば入力の処理、アニメーション、衝突などのロジック。

[[CCScheduler sharedDirector] scheduleUpdateForTarget:self priority:0 paused:NO];
から
[[[CCDirector sharedDirector] scheduler] scheduleUpdateForTarget:self priority:0 paused:NO];

P128

タッチ入力を受け取るクラスを自作する方法。
プロトコルを実装する。
P126では同じクラスにスケジュールを実装していた。
自作クラスにcocos2dの機能を実装する際には役に立ちそう。

NSObjectをベースクラスとして使うと、たとえばCCSpriteを要素として持ち、タッチ入力やスケジュールを処理できるキャラクタークラスを作成することができる。

CCProgressTimerクラス

進行状況を表すプログレスタイマー。回転、垂直、水平タイプがある。
自動的に更新されないのでscheduleUpdateなどのスケジュールが必要。

CCParallaxNodeクラス

視差。2Dゲームで奥行きがある印象を与えるための効果。
異なる速さで移動するレイヤ化された画像。

CCRibbonクラス

v2では逝ってしまったらしい。再現する場合は代替の方法を調べることになる。
線上にスプライトを描画する場合などに使用する。

CCMotionStreakクラス

基本的にはCCRibbonのラッパー。CCRibbonをフェードアウトして光跡効果。
v2でも存在するので、あとで調べて置くとよさそう。

参考:

cocos2dで作る iPhone&iPadゲームプログラミング

cocos2dで作る iPhone&iPadゲームプログラミング