Come memorizzeresti il tuo stato di gioco all'uscita per un gioco per iPhone scritto in Objective-C?
Come memorizzeresti il tuo stato di gioco all'uscita per un gioco per iPhone scritto in Objective-C?
Risposte:
Ecco il metodo che ho usato nei miei giochi.
Innanzitutto, ogni oggetto che deve essere persistito deve implementare il protocollo NSCoding. Si desidera archiviare solo i dati del modello e nulla di specifico per il processo corrente. Ciò significa che non è possibile persistere puntatori o eventuali ID risorse che il sistema operativo fornisce in fase di esecuzione. Per i puntatori puoi risolverlo facilmente assicurandoti di codificare gli oggetti a cui puntano anziché i puntatori stessi. Per altre risorse, avrai bisogno di un modo per collegare il tuo oggetto alla nuova risorsa in fase di esecuzione.
In secondo luogo, assicurati che tutti gli oggetti di gioco siano accessibili tramite un singolo oggetto radice. Questo oggetto potrebbe essere un oggetto master per l'intero stato del gioco, ad esempio. Un'altra possibilità è che sia possibile memorizzarli in una delle classi di raccolta Foundation (NSMutableArray, NSMutableSet, NSMutableDictionary).
Quando ricevi una notifica che l'applicazione si sta spostando in background (applicationDidEnterBackground), dovrai utilizzare NSKeyedArchiver per salvare l'intero stato in un file. Tale file dovrebbe trovarsi nella directory dei documenti per l'applicazione. Ecco un po 'di codice per mostrare come è fatto:
NSArray *docDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [docDirectories objectAtIndex:0];
NSString *saveFile = [docsPath stringByAppendingPathComponent:SAVE_STATE_FILENAME];
[NSKeyedArchiver archiveRootObject:gameState toFile:saveFile;
Quando rilevi di essere tornato in primo piano, dovresti rimuovere il file di salvataggio per evitare confusione al successivo avvio dell'applicazione.
All'avvio dell'applicazione, è necessario verificare l'esistenza del file di salvataggio. Se ne hai uno, lo carichi in questo modo:
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];
A seconda del tuo progetto, potresti dover attraversare lo stato del gioco e riconnettere tutte le risorse che non potresti persistere. Questo dipende in realtà dalla separazione netta del codice del modello dal codice di rendering.
A questo punto, potresti voler mettere il gioco in uno stato di pausa, a seconda del tipo di gioco che stai realizzando.
Spero che questo aiuti qualcun altro là fuori che sta cercando di implementare il salvataggio del gioco su iPhone.
Come memorizzare lo stato del gioco è una domanda complessa che dipende fortemente da come si configura il gioco stesso.
Su iPhone in particolare, si sarebbe solo dovuto collegare in -(void)applicationWillTerminate:
nella vostra UIApplicationDelegate
per prendere quando l'applicazione uscirà, da azione dell'utente o in altro modo. Tuttavia, hai poco tempo per svolgere il tuo lavoro prima che il sistema operativo interrompa il processo.
Ciò dipende in gran parte da come il tuo gioco è stato codificato. Tieni traccia di qualche ivar o di qualcosa di più sostanziale?
Se sono solo pochi ivar, probabilmente li scriverei su un plist in background e lo caricare all'avvio.
Se ci sono più ivar, potresti stare meglio con CoreData (e / o salvare i loro valori mentre cambiano invece di cercare di adattare tutto nella finestra di chiusura).
Allo stesso modo in cui lo salvi quando l'utente salta un gioco di salvataggio senza uscire.
Questa domanda è su come salvare lo stato del gioco? O come fare qualcosa all'uscita dall'app?
Per quest'ultimo, la risposta è: appWillTerminate (o appWillResignActive.) In iOS4 o versioni successive, puoi richiedere tempi supplementari (Google "iOS-4 richiesta tempi supplementari") se il tuo gioco di salvataggio impiega un po 'di tempo.
Se mi stai chiedendo come salvare lo stato del gioco, sono un grande fan di NSDictionary per memorizzare i valori facilmente rileggibili dal motore di gioco su continue.
NSMutableDictionary *saveDict = [NSMutableDictionary dictionary];
[saveDict setValue: [NSNumber numberWithInt: currentScore] forKey: @"currentScore"];
// etc...
[saveDict writeToFile: saveFilePath atomically: YES];
Se vuoi, puoi aggiungere una "firma" (ad esempio , come md5 o simile) per verificare sul gioco continuare ad assicurarti che qualcuno non abbia confuso il file per provare a imbrogliare.
Direi di no. Salvalo quando ha senso per il gioco, non quando l'app è in uscita. Ad esempio, se si tratta di un gioco a turni, salva alla fine di ogni turno. Se si tratta di un gioco basato sul livello, salva alla fine di ogni livello. Ci sono un paio di ragioni per questo:
Ecco un esempio di come implementare il protocollo NSCoding per alcune classi "map" e "player" di esempio:
http://deadpanic.com/howtosave
Quindi è possibile salvare gli oggetti utilizzando il metodo NSKeyedArchiver di Dennis.