夏までにiPhone アプリつくってみっか!

趣味でiPhone/Androidアプリを開発し、日々勉強した事を書いています。オープンワールド系レースゲームをUnityで開発中です。

【cocos2d】BGMをシークしてデータ量を削減

現在開発中のスペースハリアーシューティングゲームではスペースハリアーと同じように、テーマソングは1曲だけでその再生開始位置を面ごとにズラすことで変化をつける予定です。
つまり、1面はBGMのイントロから、2面はAメロ、3面はBメロという感じです。
cocos2dに組み込まれているSimpleAudioEngineは名前の通りシンプルな機能しかないため、曲の途中から再生する機能はありません。
開始位置が異なる曲データを複数用意すればスペースハリアーと同じ事が出来ます。
しかし、同じ曲なのにデータ量が数倍に膨れ上がるのが気に入らないので、曲の再生位置何とか変えられないか調べてみました。

見つかった情報がこれです。
そこで参照しているcocos2dのフォーラムの該当部分が今はアクセスできないのですが、
like it says in the post, you get the instance of AVAudioPlayer from the CDLongAudioSource and the set the currectTime property to 0.2 seconds before playing it
というコメントをヒントに試してみたところ成功しました。
※上で書かれているcurrectTimeはcurrentTimeの間違いのようです。

playBackgroundMusicで曲を再生したあとにこの処理を入れると曲の頭から10秒の位置から再生できます。なお、playBackgroundMusicの前に入れると上手く行きません。

            CDAudioManager* audioManager = [CDAudioManager sharedManager];
            CDLongAudioSource* bgm = audioManager.backgroundMusic;
            bgm.audioSourcePlayer.currentTime = 10.0;

私のプログラムでは曲は5つの部分に分かれて、6面では1面と同じ部分から再生するので、5で割った余りの数でswitchしています。_levelは現在の面数で、次の面のBGMが欲しいので+1しています。

        NSTimeInterval startTime;
        switch ((_level + 1) % 5) { // 次の面のBGM開始位置を設定。5面で1曲。6面は頭から
            case 0:
                startTime = 109.71;
                break;
            case 1:
                startTime = 0.0;
                break;
            case 2:
                startTime = 27.35;
                break;
            case 3:
                startTime = 54.9;
                break;
            case 4:
                startTime = 82.28;
                break;
            default:
                startTime = 0.0;
                break;
        }
        NSOperationQueue* queue = [[NSOperationQueue alloc] init];
        [queue addOperationWithBlock:^{
            [[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"GirlTheme.m4a"];
            CDAudioManager* audioManager = [CDAudioManager sharedManager];
            CDLongAudioSource* bgm = audioManager.backgroundMusic;
            bgm.audioSourcePlayer.currentTime = startTime;
        }];

NSOperationQueueはBGM切り替え時の処理落ちを防ぐために使っています。
気になる方は、
【Objective-C, cocos2d】BGMの切り替えを並列処理して画面のコマ落ちを防ぐ方法 - 夏までにiPhone アプリつくってみっか!
を参考にどうぞ。

このゲームのBGMのサイズは2.3MBなので、上記の処理を入れるだけでデータサイズを2.3 x 4 = 9.2MB減らす事が出来ました。
https://itunes.apple.com/jp/app/travelshooting-jp-toraberushutingu/id917570972?mt=8&uo=4&at=10laCt
https://itunes.apple.com/jp/app/beecluster-wu-liaono-zongsukurorushutingugemu/id663801586?mt=8&uo=4&at=10laCt