回答:
これが私のゲームで使用した方法です。
まず、永続化する必要があるすべてのオブジェクトは、NSCodingプロトコルを実装する必要があります。モデルデータのみを保存し、現在のプロセスに固有のものは何も保存しません。これは、OSが実行時に提供するポインターやリソースIDを永続化できないことを意味します。ポインターについては、ポインター自体ではなく、ポインターが指すオブジェクトを確実にエンコードすることで、これを簡単に修正できます。他のリソースについては、実行時にオブジェクトを新しいリソースにフックする方法が必要になります。
次に、すべてのゲームオブジェクトが単一のルートオブジェクトを通じてアクセスできることを確認します。このオブジェクトは、たとえば、ゲーム状態全体のマスターオブジェクトになる可能性があります。別の可能性は、それらをFoundationコレクションクラス(NSMutableArray、NSMutableSet、NSMutableDictionary)のいずれかに格納できることです。
アプリケーションがバックグラウンド(applicationDidEnterBackground)に移行することを通知されたら、NSKeyedArchiverを使用して状態全体をファイルに保存する必要があります。そのファイルは、アプリケーションのドキュメントディレクトリにある必要があります。これがどのように行われるかを示すコードの一部を次に示します。
NSArray *docDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [docDirectories objectAtIndex:0];
NSString *saveFile = [docsPath stringByAppendingPathComponent:SAVE_STATE_FILENAME];
[NSKeyedArchiver archiveRootObject:gameState toFile:saveFile;
フォアグラウンドに戻ったことを検出した場合は、保存ファイルを削除して、次にアプリケーションを起動したときの混乱を防ぐ必要があります。
アプリケーションの起動時に、保存ファイルの存在を確認する必要があります。持っている場合は、次のようにロードします。
NSArray *docDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [docDirectories objectAtIndex:0];
NSString *saveFile = [docsPath stringByAppendingPathComponent:SAVE_STATE_FILENAME];
[gameState release];
gameState = [[NSKeyedArchiver unarchiveObjectWithFile:saveFile] retain];
デザインによっては、ゲームの状態を確認し、永続化できなかったリソースを再接続する必要がある場合があります。これは、モデルコードがレンダリングコードからどの程度明確に分離されているかによります。
この時点で、作成しているゲームの種類に応じて、ゲームを一時停止状態にすることができます。
うまくいけば、これはiPhoneにゲームの節約を実装しようとしている他の誰かを助けるでしょう。
ゲームの状態を保存する方法は、ゲーム自体の設定方法に大きく依存する複雑な問題です。
iPhoneでは具体的には、あなただけにフックする必要があります-(void)applicationWillTerminate:
あなたの中UIApplicationDelegate
のアプリケーションがユーザーのアクションから、あるいはそうでない場合は、終了するときキャッチします。ただし、OSがプロセスを強制終了する前に、短時間で作業を行うことができます。
それは、ゲームのコーディング方法に大きく依存します。いくつかのivarまたはより重要なものを追跡していますか?
それがほんの数個のivarである場合、おそらくそれらをバックグラウンドのplistに書き込み、起動時にそれをロードします。
さらに多くのivarがある場合は、CoreDataを使用することをお勧めします(および/またはすべてを閉じるウィンドウに収めようとするのではなく、値が変化するときにそれらを保存します)。
ユーザーが終了せずに保存ゲームにぶつかったときに保存するのと同じ方法。
ゲームの状態を保存する方法についての質問ですか?または、アプリの出口で何かをするにはどうすればよいですか?
後者の場合、答えは次のとおりです。appWillTerminate(またはappWillResignActive)。iOS4以降では、保存ゲームに時間がかかる場合、追加の時間(Google "iOS-4 request extra time")をリクエストできます。
ゲーム状態を保存する方法を質問している場合、私はNSDictionaryの大ファンであり、継続してゲームエンジンによって値を簡単に再読み取りできます。
NSMutableDictionary *saveDict = [NSMutableDictionary dictionary];
[saveDict setValue: [NSNumber numberWithInt: currentScore] forKey: @"currentScore"];
// etc...
[saveDict writeToFile: saveFilePath atomically: YES];
必要に応じて、「署名」(つまり、md5など)を追加して、ゲームを続行し、誰かがファイルをだまして不正行為を試みていないことを確認できます。
私はそうはしません。アプリが終了するときではなく、ゲームにとって意味のあるときに保存してください。たとえば、これがターンベースのゲームである場合、各ターンの終わりにセーブします。レベルベースのゲームの場合は、各レベルの最後に保存します。これにはいくつかの理由があります。
次に、「マップ」クラスと「プレーヤー」クラスの例にNSCodingプロトコルを実装する方法の例を示します。
http://deadpanic.com/howtosave
次に、DennisのNSKeyedArchiverメソッドを使用してオブジェクトを保存できます。