読者です 読者をやめる 読者になる 読者になる

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

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

【TravelShooting JP】ゲーム開始時の処理をタイトル画面で済ませてレスポンスアップ!

TravelShooting JP cocos2d Objective-C

順調に開発が遅れているTravelShooting JPですが、そろそろタイトル画面を付けて見たくなり、タイトル画面としてcocos2dのシーンを1つ追加しました。

タイトル画面にボタンを1つ配置し、押すとゲームがスタートするようにしてみたのですが、嫌なことに気がついてしまいました。
ボタンを押してもしばらく反応がなく、1秒くらい遅れてゲームが始まります。

初期化処理に掛かる時間を実測してみると、

2014-09-03 18:13:04.120 TravelshootingJP[29379:60b] Start
2014-09-03 18:13:05.203 TravelshootingJP[29379:60b] Finish

やはり1秒以上掛かっています。
このレスポンスの悪さだとユーザーから苦情が来るのは避けられないので、とにかく準備できる処理は全てタイトル画面でやっておく事にしました。
cocos2dのシーンをまたぐので、基本的にはシングルトンインスタンスが管理するデータが対象になります。

例えば、SimpleAudioEngineのpreloadBackgroundMusicなんかはタイトル画面でやっておいても全く問題ありません。

また、スプライトシートやテクスチャーファイルも読んでおくと高速化できます。
私の場合は、プロジェクトのSpriteSheetsというディレクトリーにTexturePackerというツールからファイルを吐き出すようにしており、そこから全ファイルをキャッシュに読み出してしています。

- (void)loadSpriteSheets
{
    NSBundle* bundle = [NSBundle mainBundle];
    NSArray* paths = [bundle pathsForResourcesOfType:@"plist" inDirectory:@"SpriteSheets"];
    NSAssert(paths.count != 0, @"No sprite .plist file found");
    
    for (NSString* path in paths) { //ディレクトリ内全.plistファイルをループ
        NSString* filename = [path lastPathComponent]; //ファイル名を取り出す
        NSString* relativePath = [@"SpriteSheets/" stringByAppendingString:filename]; //Resourcesディレクトリからの相対パス
        [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:relativePath];
    }
    
    paths = [bundle pathsForResourcesOfType:@"pvr.ccz" inDirectory:@"SpriteSheets"];
    NSAssert(paths.count != 0, @"No sprite .pvr.ccz file found");
    
    for (NSString* path in paths) {
        NSString* filename = [path lastPathComponent];
        NSString* relativePath = [@"SpriteSheets/" stringByAppendingString:filename];
        [[CCTextureCache sharedTextureCache] addImageAsync:relativePath withBlock:^(CCTexture2D *tex) {
        }];
    }
}

その他、自分で作ったシングルトンクラスのインスタンスも初期化しておきます。
シングルトンインスタンスはcocos2dのノードツリーに加えておかなくても解放されないので、タイトルシーンではとりあえず初期化だけしておき、ゲームシーンでaddChildすると良いと思います。

タッチ関係のシングルトンインスタンスはタイトル画面でも使いたいのでタイトルシーンでaddChildし、replaceSceneの直前でremoveChildしています。

これらの修正を加え起動してみると、スタートボタンのタッチ後、全く遅れが気にならないくらいのレスポンスでゲームがスタートするようになりました。

時間を計ってみると、

2014-09-03 18:18:40.203 TravelshootingJP[29445:60b] Start
2014-09-03 18:18:40.452 TravelshootingJP[29445:60b] Finish

約0.25秒

かなり短縮されています。
これなら恐らく苦情は来ないと思います。