Comment stockeriez-vous l'état de votre jeu à la sortie pour un jeu iPhone écrit en Objective-C?
Comment stockeriez-vous l'état de votre jeu à la sortie pour un jeu iPhone écrit en Objective-C?
Réponses:
Voici la méthode que j'ai utilisée dans mes jeux.
Tout d'abord, chaque objet qui doit être persistant doit implémenter le protocole NSCoding. Vous souhaitez uniquement stocker vos données de modèle et rien de spécifique au processus en cours. Cela signifie que vous ne pouvez pas conserver les pointeurs ou les identifiants de ressources que le système d'exploitation vous donne au moment de l'exécution. Pour les pointeurs, vous pouvez résoudre ce problème facilement en vous assurant simplement d'encoder les objets vers lesquels ils pointent au lieu des pointeurs eux-mêmes. Pour les autres ressources, vous aurez besoin d'un moyen de connecter votre objet à la nouvelle ressource lors de l'exécution.
Deuxièmement, assurez-vous que tous vos objets de jeu sont accessibles via un seul objet racine. Cet objet peut être un objet maître pour tout l'état du jeu, par exemple. Une autre possibilité est que vous puissiez les stocker dans l'une des classes de collection Foundation (NSMutableArray, NSMutableSet, NSMutableDictionary).
Lorsque vous êtes averti que votre application se déplace en arrière-plan (applicationDidEnterBackground), vous devrez utiliser NSKeyedArchiver pour enregistrer l'intégralité de l'état dans un fichier. Ce fichier doit se trouver dans le répertoire des documents de votre application. Voici un peu de code pour montrer comment cela se fait:
NSArray *docDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [docDirectories objectAtIndex:0];
NSString *saveFile = [docsPath stringByAppendingPathComponent:SAVE_STATE_FILENAME];
[NSKeyedArchiver archiveRootObject:gameState toFile:saveFile;
Lorsque vous détectez que vous êtes revenu au premier plan, vous devez supprimer le fichier de sauvegarde pour éviter toute confusion lors du prochain lancement de votre application.
Au démarrage de l'application, vous devez vérifier l'existence du fichier de sauvegarde. Si vous en avez un, vous le chargez comme ceci:
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];
Selon votre conception, vous devrez peut-être parcourir l'état du jeu et reconnecter toutes les ressources que vous ne pourriez pas conserver. Cela dépend vraiment de la séparation nette de votre code de modèle avec votre code de rendu.
À ce stade, vous souhaiterez peut-être mettre votre jeu en pause, selon le type de jeu que vous créez.
Espérons que cela aide quelqu'un d'autre qui essaie d'implémenter la sauvegarde de jeu sur l'iPhone.
Comment stocker l'état du jeu est une question complexe qui dépend fortement de la façon dont vous configurez votre jeu lui-même.
Sur l'iPhone en particulier, il vous suffira de vous connecter -(void)applicationWillTerminate:
à votre UIApplicationDelegate
pour attraper le moment où l'application se fermera, de l'action de l'utilisateur ou autrement. Cependant, vous avez peu de temps pour faire votre travail avant que le système d'exploitation ne tue votre processus.
Cela dépendrait en grande partie de la façon dont votre jeu a été codé. Gardez-vous une trace de quelques ivars ou quelque chose de plus substantiel?
S'il ne s'agit que de quelques ivars, je les écrirais probablement sur un plist en arrière-plan et les chargerais au démarrage.
S'il y a plus d'ivars, vous pourriez être mieux avec CoreData (et / ou enregistrer leurs valeurs au fur et à mesure qu'elles changent au lieu d'essayer de tout rentrer dans la fenêtre de fermeture).
De la même manière que vous l'enregistrez lorsque l'utilisateur saute une sauvegarde sans quitter.
Cette question concerne-t-elle la sauvegarde de l'état du jeu? Ou comment faire quelque chose à la sortie de l'application?
Pour ce dernier, la réponse est: appWillTerminate (ou appWillResignActive.) Dans iOS4 ou version ultérieure, vous pouvez demander du temps supplémentaire (Google "iOS-4 request extra time") si votre sauvegarde prend du temps.
Si vous demandez comment enregistrer l'état du jeu, je suis un grand fan de NSDictionary pour stocker les valeurs facilement relues par le moteur de jeu.
NSMutableDictionary *saveDict = [NSMutableDictionary dictionary];
[saveDict setValue: [NSNumber numberWithInt: currentScore] forKey: @"currentScore"];
// etc...
[saveDict writeToFile: saveFilePath atomically: YES];
Si vous le souhaitez, vous pouvez ajouter une "signature" ( c'est-à - dire , comme md5 ou similaire) pour vérifier sur le jeu continuer à vous assurer que quelqu'un n'a pas foutu le fichier pour essayer de tricher.
Je dirais que non. Enregistrez-le lorsque cela a du sens pour le jeu, pas lorsque l'application se ferme. Par exemple, s'il s'agit d'un jeu au tour par tour, enregistrez à la fin de chaque tour. S'il s'agit d'un jeu basé sur le niveau, enregistrez à la fin de chaque niveau. Il y a plusieurs raisons à cela:
Voici un exemple de la façon d'implémenter le protocole NSCoding pour certains exemples de classes "map" et "player":
http://deadpanic.com/howtosave
Ensuite, vous pouvez enregistrer les objets à l'aide de la méthode NSKeyedArchiver de Dennis.