『cocos2d for iPhone レッスンノート』のメモ

読書

P27 ファイルの意味

*****-Info.plist
XML形式のファイルです。ホーム画面でアプリアイコンの下に表示されるアプリ名や、バージョン番号などの設定を記述するためのファイルです。

*****-Prefix.pch
プリコンパイルヘッダーです。

*****Tests.h / .m
アプリの単体テストを行うためのクラス(SenTestCaseクラスから継承されている)が記述されているファイルです。

P40 1.5.4 ノード

CCNodeクラスとそのサブクラスを意味する「ノード」は、シーン上に配置できるオブジェクトの総称として使われます。前述のスプライト、シーン、レイヤーもCCNodeのサブクラスなのでノードです。

CCNodeクラスでは、オブジェクトの座標・サイズ・他ノードとの前後関係などといった、ゲームの中で存在するためのプロパティを持っています。レイヤーやスプライトの項目で説明したとおり、ノード自身にノードを保持できるようになっているのが特徴です。

P40 1.5.5 アクション、トランジション

「アクション、トランジション」は、ノードに対して動作やエフェクトを行わせるための機能です。アクションはノードに対するアニメーションやエフェクトを指すのに対して、トランジションはシーンを切り替えるときに使えるアニメーションやエフェクトを表します。

ノードに対してアクションを登録すると、スケジューラによって自動的に実行されます。アクションはキューによって管理されるため、複数のアクションを先に登録しておき、順番に実行させたりもできます。

P41 1.5.6 スケジューラ

「スケジューラ」は、ノードのタイマー処理や画面の更新、それにアクションの実行といったcocos2d上で発生するすべてのイベントを管理しています。たとえば敵キャラクターを移動させたいような場合は、スケジューラに対して敵キャラクターのオブジェクトを登録しておき、定期的に呼ばれるメソッドの中で座標を更新します。NSTimerクラスと異なり、cocos2dの動作状況と連携して動作するのが特徴です。

P47 スケジューラに登録する関数

- (void) nextFrame:(ccTime)deltaTime {
  // 内容
  static int test = 0;
  test = deltaTime * 100; // 1秒で testの値 (deltaTime * 100 の総和) は 約100 となる。
}

deltaTimeはおおよそ 1 / FPS くらいの値が入っており、 処理に遅延がなければ 1秒間に FPS 回 このメソッドがコールされることになる。

P59 ゲームをデザインする

  • アピールポイントは? 何が面白いゲームなの?
  • 対象ユーザー像は? どういう人に遊んでほしい?
  • ゲームの世界観・テーマ・核となるものは? - 作ろうとするゲームの世界を明確にする
  • ゲームの完成はどこか? - 不要な作りこみはNG

P66 2.3.1.2 乱数列を初期化する

cocos2dでは乱数が得られるユーティリティーマクロとして CCRANDOM_0_1()CCRANDOM_MINUS1_1() が用意されていて、 内部で libcrandom() 関数を使用しています。 しかし srandom() などの種を渡す処理が記述されてないため、 そのままだとアプリが起動して後は常に同じ乱数列が得られることになり、 ゲームがパターン化してしまうのです。

NOTE : random() 関数は種を与えないで呼び出した場合、種を1として乱数列を作成します。 したがって、現在時刻によって乱数列を変化させておき、ゲームにランダムさを正しく持ってきておくことがポイントです。 AppDelegate.mの先頭でメソッド宣言を記述した上で、実装部の適当な箇所で初期化処理用のinitRandomメソッドを記述します。

- (void) initRandom {
  struct timeval t;
  gettimeofday(&t, nil);
  unsigned int i;
  i = t.tv_sec;
  i += t.tv_usec;
  srandom(i);
}

P90 InterfaceLayer.m のコードの一部抜粋

- (void) onEnter {
// タッチ操作を有効にする
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];

[super onEnter];
}

- (void) onExit {
// タッチ操作を無効にする
[[CCTouchDispatcher sharedDispatcher] removeDelegate:self];

[super onExit];
}

P97 のカードを入れ替える処理のコード

CCTextureCache から CCTexture2D を取得して画像を変更する処理だね。 でも普通は CCSpriteBatchNode を使うから setTextureRect を使用することのほうが多いと思われる。

- (void) tapCard:(Card*)card sprite:(CCSprite*)sprite {
  NSString* fileName = [NSString stringWithFormat:@"card%d.png", card.type + 1];
  [sprite setTexture:[[CCTextureCache sharedTextureCache] addImage:fileName]];
}

CCDirector#runningScene

このメソッドは現在実行中のシーンのポインタを返す。

CCNodetag の使い方

// タグ値を指定してノードを追加
[layer addChild:sprite z:4 tag:2];

// タグ値からノードを取得
CCNode *node = [layer getChildByTag:2];

// タグ値からノードを削除
[layer removeChildByTag:2 cleanup:YES];

P161 ノードのイベント

Transition なしの場合は

  • [移動先] init
  • [移動元] onExit
  • [移動元] dealloc
  • [移動先] onEnter
  • [移動先] onEnterTransitionDidFinish

の順にコールされる。

Transition ありの場合は

  • 1.[移動先] init
  • 2.[移動先] onEnter
  • -. アニメーション
  • 3.[移動元] onExit
  • 4.[移動先] onEnterTransitionDidFinish
  • 5.[移動元] dealloc

親クラスの onEnter, onExit, onEnterTransitionDidFinish を実行するのを忘れずに!

P177 Objective-C でのシングルトンの作り方

実は、GameScene で使用したシングルトンの作り方だと、厳密な意味でのシングルトンにはなっていません。オブジェクトのコピーができたり、マルチスレッド環境下での排他処理が適切に行われていなかったり、オブジェクトの release できたりと、プログラム中で唯一であることが保証されていないためです。Objective-Cでの厳密なシングルトンを作る場合は、以下の方法を適用する必要があります。

※Appleのドキュメントでは https://developer.apple.com/legacy/library/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW32 に載っています。(追記: もう古くて役に立たないかも)

  • allocWithZone: メソッドをオーバーライドして、alloc 時に同じ静的変数を参照する
  • retain/release/autorelease メソッドをオーバーライドして、参照カウンタを操作させない
  • copyWithZone: メソッドをオーバーライドしてコピーさせない
  • メモリ操作を行うときは @synchronized で排他制御する

しかし厳密な方法だとオーバースペックになってしまうため、本章では「コピーしない」「開放しない」「参照カウンタを操作しない」といった、使う側がルールを守るようにして、半シングルトンとして作成・動作するようにしています。Objective-C におけるデザインパターンについては、書籍「Dynamic Objective-C」(木下誠著、株式会社ピー・エヌ・エヌ新社刊)に詳しい説明が載っているので、こちらを参考にするとよいでしょう。

cocos2d 内部だと、CCDirector クラスが Asteroids ゲームと同じ方法で実装されています(一方で CCActionだと、より厳密にシングルトンが作成する方法で実装されていてばらつきがあるのですが・・・)。

P180 パーティクル

    // 雨のような表現をするCCParticleRainのパラメータを調節して星空を実現する
    self.space = [CCParticleRain node];
    self.space.emissionRate = 10; // パーティクルの同時表示数が多すぎる パーティクルの表示数を少なく-> emissionRate を小さく
    self.space.startSize = 2.5f; // パーティクルのサイズを小さく -> startSize を小さく
    self.space.gravity = ccp(0,0); // 重力で加速しない -> gravity を (0, 0) として、重力加速度を一定にする
    self.space.speed = 30; // スピードを遅く-> speed を小さく
    self.space.life = 10; // 消滅するまでの時間を長く-> life を大きく
    self.space.angleVar = 0; // 一部のパーティクルが左右に動く 移動中に揺れなくしたい -> angleVar, radialAccelVar を 0 にする
    self.space.radialAccelVar = 0; //
    self.space.tangentialAccelVar = 0; //
    [self addChild:self.space z:0];

P210

// P.210
// CCParticleSun をベースにパラメータを調節して爆発を表現します
CCParticleSystem *bomb = [CCParticleSun node];
bomb.duration = 0.3f; // パーティクルは一瞬で消えて欲しい -> duration を短く
bomb.life = 0.5f; // 爆発後も爆風が広がってほしい -> life を duration より若干長く
bomb.speed = 40; // 爆発らしく広がってほしい -> speed を大きく
bomb.scale = self.scale * 2.0f; // 爆風の大きさを敵キャラクターの大きさで変化させたい -> scale を Enemy のサイズで変化させる
bomb.position = self.position; // 爆風は敵キャラクターの位置で発生して欲しい -> position を Enemy と同じ位置に
bomb.autoRemoveOnFinish = YES; // 爆発後は自動的にメモリ解放して欲しい -> autoRemoveOnFinish プロパティをYESに

CCParticleRain 以外のパーティクルシステムを使いたい場合でも、 説明した内容と同様の初期化方法が使えます。 Particle Designer などのツールで作成した plist形式のファイルも読み込めます。

CCParticleSystem *emitter = [CCParticleSystemQuad particleWithFile:@"MyParticle.plist"];

パーティクルシステムとして設定可能なパラメータ(P280)

パラメーター説明
durationパーティクルシステムとしての寿命。消滅させない場合は kCCParticleDurationInfinity を指定
sourcePositionエミッターの位置。ゆらぎは posVar で指定
life各パーティクルの寿命。ゆらぎは lifeVar で指定
angle各パーティクルの移動角度。ゆらぎは angleVar で指定
startSizeパーティクル誕生時のサイズ。ゆらぎは startSizeVar で指定(CCParticleSystemPoint は64ポイント以下)
endSizeパーティクル消滅時のサイズ。誕生時と同じサイズを維持する場合は kCCParticleStartSizeEqualToEndSize を指定。ゆらぎは endSizeVar で指定(CCParticleSystemPoint は64ポイント以下)
startColor・endColorパーティクル 誕生時・消滅時 の色。ゆらぎは startColorVar・endColorVar で指定
startSpin・endSpinパーティクル誕生・消滅時の回転角度。ゆらぎは startSpinVar・endSpinVar で指定(CCParticleeSystemQuad のみ指定可能)
emissionRateパーティクルの生成レート
totalParticles生成するパーティクルの総数
textureテクスチャ画像
blendFuncブレンドに用いる方法を ccBlendFunc で指定
blendAdditiveYES の場合は srcGL_SRC_ALPHAdestGL_ONE を使用
positionTypeパーティクルを配置する親ノードの動きに対してどう振る舞うかを tCCPositionType で指定
autoRemoveOnFinishパーティクルシステムの動作完了時に自動的にcleanUpするかどうか。デフォルトはNO
emitterModeエミッターのモード。Gravity(kCCParticleModeGravity) または Radius(kCCParticleModeRadius) を指定

emitterModeGravity のときに利用できるパラメータ

パラメーター説明
gravity重力が存在する場所。CGPoint で座標を指定する(画面外も指定可能)
speedパーティクルがエミッターから放出された時の初期速度。ゆらぎは speedVar で指定
tangentialAccleパーティクルの接線加速度。エミッターから放出された後の曲がり具合を指定する。ゆらぎは tangentialAccelVar で指定
radialAccelパーティクルの半径方向加速度。 エミッターから放出された後の加速度を指定する。ゆらぎは radialAccelVar で指定

emitterModeRadius のときに利用できるパラメータ

startRadius | パーティクル誕生時の、エミッターからの距離(半径)。ゆらぎは startRadiusVar で指定 endRadius | パーティクル消滅時の、エミッターからの距離(半径)。誕生時と同じ距離を維持したい場合は kCCParticleStartRadiusEqualToEndRadius を指定。ゆらぎは endRadiusVar で指定 rotatePerSecond | 1秒当たりのパーティクルの回転角度

設定するときは、標準提供されたパーティクル用のクラスか CCParticleSystemQuad / CCParticleSystemPoint クラス(およびそのサブクラス)のオブジェクトに設定します。

P235 パーティクルシステムを自分で作成したい場合には、ARCH_OPTIMAL_PARTICLE_SYSTEM マクロを使ってクラスを定義してください。

@interface NyAwesomeParticle : ARCH_OPTIONAL_PARTICLE_SYSTEM

このマクロは CCParticleExamples.h で定義されていて、 アプリを動かすときのターゲットによって適切なパーティクルシステムを選んでくれるためです。

一時的な効果のためにパーティクルを使用したい場合、 使用後には removeFromParentAndCleanup: メソッドなどでパーティクルを親から削除するか、 あるいはパーティクルの autoRemoveOnFinish = YES; としておいて、動作終了後に自動削除されるようにしてください。

P236 パーティクルシステムを作成するソフト

seventyone^2 の「Particle Designer」(https://71squared.com/particledesigner)

Particle Designer で作成したパーティクルシステムを cocos2d で扱う場合、 plist 形式で書きだしたデータを、CCParticleSystem クラスの particleWithFile: メソッドで読み込みます。

CCParticleSystem *emitter;
emitter = [ARCH_OPTIONAL_PARTICLE_SYSTEM particleWithFile:@"MyParticle.plist"];
[self addChild:emitter];

P186 CCScheduler

  • #scheduleUpdate ・ unscheduleUpdate
    #update: メソッドのスケジュールを有効・無効にするメソッド。 スケジュールを有効にすると、レイヤーがアクティブの時にフレーム毎に update: メソッドがコールされる。
  • #update:(ccTime) dt
    フレーム毎に実行されるメソッド。#scheduleUpdateメソッドで有効化できる
  • #unscheduleAllSelectors
    スケジューラに登録していたセレクタを全て停止する
  • #schedule:(SEL) interval:(ccTime)
    スケジューラにセレクタを登録する。interval でスケジュールの感覚を設定できる。#schedule: メソッドの場合は interval = 1 / FPS となる。#unschedule:(SEL) で登録を解除できる。

P.213 gridプロパティを操作するアクション (CCGridAction)

  • CCFlipX3D
  • CCFlipY3D
  • CCLens3D
  • CCLiquid
  • CCRipple3D
  • CCShaky3D
  • CCTwirl
  • CCWaves
  • CCWaves3D

タッチイベントのハンドリング

タッチ操作は CCStandardTouchDelegate or CCTargetedTouchDelegate を実装することで可能となる

/**
 CCTargetedTouchDelegate.

 Using this type of delegate results in two benefits:
 1\. You don't need to deal with NSSets, the dispatcher does the job of splitting
 them. You get exactly one UITouch per call.
 2\. You can *claim* a UITouch by returning YES in ccTouchBegan. Updates of claimed
 touches are sent only to the delegate(s) that claimed them. So if you get a move/
 ended/cancelled update you're sure it's your touch. This frees you from doing a
 lot of checks when doing multi-touch.

 (The name TargetedTouchDelegate relates to updates "targeting" their specific
 handler, without bothering the other handlers.)
 @since v0.8
 */
@protocol CCTargetedTouchDelegate <NSObject>

/** Return YES to claim the touch.
 @since v0.8
 */
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event;
@optional
// touch updates:
- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event;
- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event;
- (void)ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event;
@end

/**
 CCStandardTouchDelegate.

 This type of delegate is the same one used by CocoaTouch. You will receive all the events (Began,Moved,Ended,Cancelled).
 @since v0.8
*/
@protocol CCStandardTouchDelegate <NSObject>
@optional
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
@end

CCStandardTouchDelegate は マルチタッチのデータを一度の受け取れる。 これを使う場合は isTouchEnabled = YES;glView.multipleTouchEnabled = YES; のフラグを立てる必要がある。

CCTargetedTouchDelegate は シングルタッチのみを扱う場合は便利。 マルチタッチを扱う場合、タッチの数だけデリゲートメソッドが呼ばれる。

P233 アクションのイージング

// 2秒かけて、中心から (+100, +100) の座標まで SineIn で移動し
// その後2秒かけて、ちゅうしんまで ElasticIn で移動する
id action01 = [CCMoveBy actionWithDuration:2.0 position:ccp(100, 100)];
id action01a = [CCEaseSineIn actionWithAction: [[action01 copy] autorelease]];
id action01b = [CCEaseElasticIn actionWithAction:[[[action01 copy] autorelease] reverse]];
[aSprite runAction:[CCSequence actions:action01a, action01b, nil];

P276 イージングの種類

  • CCEaseIn/CCEaseOut/CCEaseInOut : f(t) = t^rate : 動作の緩急をおおきくしたい場合は rate に大きな値を指定する
  • CCEaseExponentialIn/CCEaseExponentialOut/CCEaseExponentialInOut : 指数式を使ったアクション
  • CCEaseSingIn/CCEaseSineOut/CCEaseSineInOut : サイン式を使用
  • CCEaseElasticIn/CCEaseElasticOut/CCEaseElasticInOut : バネが伸び縮みするようなアクション。元々の移動範囲よりも大きく移動します。このクラスでは、イージングのパラメータとして period を指定できるようになっています。デフォルトは 0.3 で、値が小さいほど激しく動きます。
  • CCEaseBounceIn/CCEaseBounceOut/CCEaseBounceInOut : ボールが弾むようなアクション
  • CCEaseBackIn/CCEaseBackOut/CCEaseBackInOut : 一旦反対方向に勢いをつけてから、目的の方向へと動くようなアクション。元々の移動範囲よりも大きく移動する。

P233 アクションについて

CCRepeatForever クラスを使ったアクションを使う場合、 CCSequence / CCSpawn クラスの中で扱うことはできない。

P256 iTunesConnect の登録の Rating について

  • Cartoon or Fantasy Violence : 漫画的な暴力的表現
  • Realistic Violence : 現実的な暴力表現
  • Sexual Content or Nudity : 性的なコンテンツ
  • Profanity or Crude Humore : 冒涜、露骨なユーモア
  • Alcohol, Tabacco, or Drug Use or References : アルコール、タバコ、薬物の使用またはリファレンス
  • Mature / Suggestive Theme : 性的な含みのあるテーマ
  • Simulated Gambling : シュミレートされたギャンブル
  • Horror / Fear Themes : ホラー・恐怖のテーマ
  • Prolonged Graphic or Sadistic Realistic Violence : サディスティックな暴力
  • Graphic Sexual Content and Nudity : 性的なコンテンツと裸体画

該当しない場合は [None] を選択します。 多少該当する場合は [Infrequent/Mild] を選択します。 該当する場合は [Frequent/Intense] を選択します。

ブレンドモード

// コピー合成
#define kBlendCopy          (ccBlendFunc) {GL_ONE, GL_ZERO}
// アルファ合成
#define kBlendAlpha         (ccBlendFunc) {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA}
// 加算合成(α有り)
#define kBlendAdditionAlpha (ccBlendFunc) {GL_SRC_ALPHA, GL_ONE}
// 加算合成(α無し)
#define kBlendAddition      (ccBlendFunc) {GL_ONE, GL_ONE}
// スクリーン合成
#define kBlendScreen        (ccBlendFunc) {GL_ONE_MINUS_DST_COLOR, GL_ONE}
// XOR合成
#define kBlendXOR           (ccBlendFunc) {GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR}
// 乗算合成
#define kBlendMult          (ccBlendFunc) {GL_ZERO, GL_SRC_COLOR}
// 反転合成
#define kBlendInversion     (ccBlendFunc) {GL_ONE_MINUS_DST_COLOR, GL_ZERO}

P227 Simple Audio Engine で効果音を鳴らす

#import "SimpleAudioEngine.h"

- (void) startBGM {
    // BGMの音量調整と再生
    [SimpleAudioEngine sharedEngine].backgroundMusicVolume = 0.5f;
    [[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"music.mp3" loop:YES];
}

- (void) soundBlast {
  // 爆発音を再生します
  // ポイントは敵キャラクターの大きさに応じてピッチを低く、ゲインを高くしている点です。
  // 単に playEffect: メソッドで再生することも出来ますが、
  // ゲームプレイ時のリアリティが変わってくるため、このような工夫をしています。
  [[SimpleAudioEngine sharedEngine] playEffect:@"blast.caf" pitch:2.0 - self.scale pan:0.5 gain:self.scale];
}

P228 サウンド再生に適したファイルの作成方法

CocosDenshion(OpenAL) で扱うサウンドファイルは、レスポンスなどの性能を考えると IMA4方式のCAFファイルで取り扱うべきです。使用するサウンドファイルが別フォーマットの場合は、Mac OS X のターミナル上で afconvert コマンドを使用して、サウンドを変換してからプロジェクトに登録しましょう。

afconvert -f caff -d ima4@22050 ファイル名

ただし、IMA4 だと圧縮率が低くファイルサイズも大きめになるため、BGM のような長いサウンドは MP3 形式で保存しておくべきです。

ちなみに CocosDenshion が使う OpenAL 環境ではサウンドの再生位置(パン) を左右に振ることができますが、 そのためには再生するサウンドファイルがモノラルになっている必要があります。 afconvert でサウンドをモノラルにする倍は 「 -c 1 」オプジョンを指定します。

P288 CocosDenshion

CocosDenshionOpenAL を最下層として、いくつかの層にわかれた設計になっています

  • CocosDenshion -> CDAudioManager -> CDSoundEngine -> OpenAL
  • OpenAL - OSが提供するオーディオライブラリ
  • CDSoundEngine - OpenALベースのサウンドエンジン
  • CDAudioManager - サウンド再生の詳細な操作
  • SimpleAudioEngine - 効果音やBGMの基本的な操作

    // サウンドファイルのプリロード
    SimpleAudioEngine *e = [SimpleAudioEngine sharedEngine];
    [e preloadEffect:@"ファイル名.caf"];
    [e preloadBackgroundMusic:@"ファイル名.mp3など"];
    
    // 効果音の再生
    [e playEffect:@"soundEffect,caf"];
    // BGMの再生(ループ再生)
    [e playBackgroundMusic:@"bgm.mp3"];
    // BGMの一時停止
    [e pauseBackgroundMusic];
    // 一時停止していたBGMを再開
    [e resumeBackgroundMusic];
    // BGMの停止
    [e stopBackgroundMusic];
    // BGMを最初から再生
    [e rewindBackgroundMusic];
    
    // 効果音の音量設定 0.0f ~ 1.0f の範囲で指定
    e.effectsVolume = 1.0f;
    // BGMの音量設定
    e.backgroundMusicVolume = 0.75f;
    
    // ミュート
    e.mute = YES;
    e.mute = NO;
    
    // ピッチ(音程)・パン(左右の位置)・ゲイン(設定したボリュームに対する利得)の指定
    // パンを指定する場合、サウンドモードはモノラルでなければいけません。
    // BGM はピッチ/パン/ゲインを変更することはできません。
    // 注意点 : これらを指定するとCPU負荷が若干上がってしまう
    [e playEffect:@"soundEffect.caf"
        pitch:0.5f // 0.5 (1オクターブ下) ・2.0(1オクターブ上)ッ
          pan:0.5f // -1.0(左) ~ 0.0(中央) ~ 1.0(右)
         gain:0.5f // -0.5(-6dB) ~ 0.5f(6dB)
    ];
    
    // アンロード
    [e unloadEffect:@"soundEffect.caf"];

SimpleAudioEngin のサウンドをフェードイン/アウトさせる

// cocos2dプロジェクトからCDXPropertyModifierAction.h/.m の2つのファイルを
// 自分のプロジェクトにもってきてインポートする
#import "CDXPropertyModifierAction.h"
// 無音からフェードイン
- (void) fadeInBgm {
  SimpleAudioEngine *e = [SimpleAudioEngine sharedEngine];

  e.backgroundMusicVolume = 0.0f;
  [e playBackgroundMusic:@"bmg.mp3"];

  [CDXPropertyModifierAction fadeBackgroundMusic:1.0f // フェードさせる時間(1秒)
                                     finalVolume:1.0f // 最終的な音量(最大)
                                       curveType:kIT_Linear // 変化のカーブ(線形)
                                       shoudStop:NO]; // フェード後の再生停止
}

// フェードアウト
- (void) fadeOutBgm {
  SimpleAudioEngine *e = [SimpleAudioEngine sharedEngine];

  [CDXPropertyModifierAction fadeBackgroundMusic:1.0f // フェードさせる時間(1秒)
                                     finalVolume:0.0f // 最終的な音量(無音)
                                       curveType:kIT_Linear // 変化のカーブ(線形)
                                       shoudStop:YES]; // フェード後の再生停止
}

CocosDenshion の情報源

公式ドキュメント CocosDenshion FAQ, CocosDenshion Cookbook でググる。

サンプルプロジェクトのターゲット名 - CocosDenshion - Drum Pad, CocosDenshion - Fade To Grey, CocosDenshion - FancyRat Metering

公式フォーラム http://www.cocos2d-iphone.org/forum/forum/6

Objective-C の情報源

iOS Developer Library - Coding How-To's, Sample Code

Share