だいたい47度

スポンサーサイト

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

PageTop

Box2Dを知るためLearning Cocos2Dを読む(4)Part III From Level to Game

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

全5部17章構成で、今回は3部の7-9章を読みます。内容としては、Part IIまでで作ったゲームにメニュー画面・音楽を追加します。また、スクロール機能を使ってステージ2を実装します。スクロール部分は僕が以前作ったアプリでは実装しなかったので学ぶことが多そうです。

【過去】
Learn Cocos2Dを手にとった理由
Part I Getting Started with Cocos2D
Part II More Enemies and More Fun

前回はcocos2dで作る iPhone&iPadゲームプログラミングに従ってSingletonもどきのコードを書いたのですが、Learning Cocos2Dではallocで処理していてよりSingletonっぽかったのでメモっておきます。synchronizedアノテーションを使ってマルチメソッドも考慮してます。
//GameManager.m
static GameManager* _sharedGameManager = nil;

+ (GameManager*)sharedGameManager{
@synchronized([GameManager class]){
if (!_sharedGameManager) [[self alloc] init];
return _sharedGameManager;
}
return nil;
}

+ (id)alloc{
@synchronized([GameManager class]){
NSAssert(_sharedGameManager == nil, @"Attempted to allocate a 2nd instance");
_sharedGameManager = [super alloc];
return _sharedGameManager;
}
return nil;
}

Chapter 7 Main Menu, Level Completed, and Credit Scenes
SingletonのGameManagerを使って各シーンの移動を実装します。メインメニューのためのCCMenuの説明もあります。

CCMenuItemのtagを使うとselectorでの処理がキレイに書けるのですね。selectorに渡す関数では、呼び出し元のCCMenuItemが引数に渡されますが、いままでどのitemが渡されたのかのチェックにちょっと面倒なコードを書いていたので、tagを使う方法が学べてよかったです。

- (void)displayMenu{
CCMenuItem* someItem1 = [CCMenuItem itemWithTarget:self selector:@selector(hoge:)];
[someItem setTag:1];
CCMenuItem* someItem2 = [CCMenuItem itemWithTarget:self selector:@selector(hoge:)];
[someItem setTag:2];
...
}

- (void)hoge:(CCMenuItem*)item{
if ([item tag] == 1) CCLOG(@"CCMenuItem someItem1 is selected.");
if ([item tag] == 2) CCLOG(@"CCMenuItem someItem2 is selected.");
}


Chapter 8 Pump Up the Volume!
音系の話を展開します。機能制限のあるAVAudioPlayerやAPIが煩雑なOpenALの代わりにCocosDenshionが作られ、SimpleAudioEngineが生まれたとか。

本章ではマルチスレッドを使ってバックグラウンドで音楽のロードをしています。マルチスレッドについては使ったことがなかったので、目新しいです。長くなるので省略しますが、NSOperationとNSInvocationOperationを使ってマルチスレッドを実装します。ここらへんは要勉強だな。

CDAudioManagerのinitAsynchronouslyを使うと、他アプリケーションのBGMを引き継いで使ったり、エフェクトだけ鳴らしたりとかもできるらしいです。
//すでに音楽がなっている状態でアプリを起動するとsound effectのみロードする
[CDAudioManager initAsynchronously:kAMM_FxPlusMusicIfNoOtherAudio];

//audio managerの起動待ち
while ([CDAudioManager sharedManagerState] != kAMStateInitialised) {
[NSThread sleepForTimeInterval:0.1];
}
CDAudioManager* audioManager = [CDAudioManager sharedManager];

...省略...//audioManagerの起動確認

[audioManager setResignBehavior:kAMRBStopPlay autoHandle:YES];
soundEngine = [SimpleAudioEngine sharedEngine];

SimpleAudioEngineのAPIでは足りない場合は、CocosDenshion, CDAudioManager, CDSoundEngineを使えば最悪OpenALレベルでの制御ができるそうな。例えば、効果音の早送りや左右どちらかから出すというのは、SimpleAudioEngineのplayEffect: pitch: pan: gain:で呼び出せますが、効果音をfadeoutさせる場合などはCocosDenshionのCDSoundSourceなどが使えるそうです。

Chapter 9 When the World Gets Bigger: Adding Scrolling
さて今回のメイン、スクロールです。段階を追って実装していきます。

まずスクロールをシンプルに実装しています。画面サイズの横幅n倍のスクロールレイヤを作り、キャラクタが画面の中央より右にいれば右にスクロール、左にいれば左にスクロールするようにします。これは、各フレームで呼び出されるupdateの際に、スクロールするlayerのpositionを変えてやるだけです(全キャラクタがスクロールレイヤ上に描かれているという実装の場合)。

ちなみにCCFollowを使う方法もあるそうです。以下のような感じにすれば、targetにitemがついていくので、targetに主人公spriteを渡してやれば良い。ただ、itemにlayerを突っ込む際はX軸方向だけでなくY軸方向も付いて行ってしまうことに注意(ジャンプすると画面も動いてしまう)。

id followAction = [CCFollow actionWithTarget:target];
[item runAction:followAction];


次にParallaxな動きを実装します。近くのものは速く、遠くのものは遅く動くアレです。cocos2dで作る iPhone&iPadゲームプログラミングでは各背景をbatchNodeに登録してそれぞれの動きを実装していましたが、本書ではCCParallaxNodeを使って簡易に実装しています。CCParallaxNodeの位置に、parallaxRatioが比率として掛けられ、positionOffsetが足されることで各レイヤの位置が決められます。
CCParallaxNode* parallaxNode = [CCParallaxNode node];
[parallaxNode addChild:layerSpr1 z:40 parallaxRatio:ccp(1.0f, 1.0f) positionOffset:ccp(0.0f, 0.0f)];
[parallaxNode addChild:layerSpr2 z:20 parallaxRatio:ccp(0.2f, 1.0f) positionOffset:ccp(0.0f, 0.0f)];
[self addChild:parallaxNode];

その次はSpriteをエンドレスに流し続ける方法が説明されていますが簡単なので省略。ここまでの完成品がアプリのステージ2にあたります。

最後にTile Mapsを使ってとても広いシーンを低メモリ消費で作成します。画面全体を覆う画像を2枚も貼ればiPhone4でもFPSが落ちるので、広い画面ではTile Mapsは必須だと思います。ツールはTiled Qtを使います。

Tiledでレイヤを複数作り、tmxファイルとpngファイルを作成、各レイヤをCCParallaxNodeに追加するだけです。CCNodeは親を一つしか持てないので、一時的にretainしてCCTMXTiledMapから外した後、CCParallaxNodeに追加するという手順を踏みます。
CCTMXTiledMap* tiledMap = [CCTMXTiledMap tiledMapWithTMXFile:@"tiledMap.tmx"];
CCTMXLayer* layer1 = [tiledMap layerNamed:@"layer1"];
CCTMXLayer* layer2 = [tiledMap layerNamed:@"layer2"];

CCParallaxNode* parallaxNode = [CCParallaxNode node];

//change the parent of layer1 from CCTMXTiledMap to CCParallaxNode
[layer1 retain];
[layer1 removeFromParentAndCleanup:NO];
[parallaxNode addChild:layer1 z:10 parallaxRatio:ccp(1,1) positionOffSet:ccp(0,0)];
[layer1 release];

......//same process to each layers


ゲームを作るステップの最初として、Tiled上でゲーム画面を描画してしまうとよいと書いてありました。確かにゲームの全体像が見えてから作った方が戻りもないし、キレイな構造になるんですよね。画像を集めるのが先になるのがどうもヤル気を削ぎますが、でも次はそうやって作ってみよう……。

なお、cocos2dで作る iPhone&iPadゲームプログラミングでもTile Mapsの説明がありますが、本書が横スクロールアクションでのTile Maps使用を説明にするのに対し、あちらはRPGのフィールドのようなTile Mapsの説明となります。等角タイルマップについても1章割いて扱っているので、RPG系はあっちの方がよいかもしれんです。


んー今回は思ったより音楽周りがタメになったなー。これで書籍全体の半分が終わりました。
次回はとうとう物理エンジンです!Part IVは長いから何回かに分けると思います。

あと、前に作ったアプリが今日付けで発売となりました!わーい。Learning Cocos2Dを読む前の僕のレベルでもこのくらいは作れるという目安になるかと思います。ぜひご覧ください。ではまた次回


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ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。