Como você armazenaria o estado do seu jogo na saída de um jogo para iPhone escrito em Objective-C?
Como você armazenaria o estado do seu jogo na saída de um jogo para iPhone escrito em Objective-C?
Respostas:
Aqui está o método que eu usei nos meus jogos.
Primeiro, todo objeto que precisa ser persistido deve implementar o protocolo NSCoding. Você deseja armazenar apenas os dados do modelo e nada específico para o processo atual. Isso significa que você não pode persistir ponteiros ou identificações de recursos que o sistema operacional fornece a você em tempo de execução. Para os ponteiros, você pode corrigir isso facilmente, apenas codificando os objetos para os quais eles apontam, em vez dos ponteiros. Para outros recursos, você precisará de uma maneira de conectar seu objeto ao novo recurso em tempo de execução.
Segundo, verifique se todos os objetos do seu jogo podem ser acessados através de um único objeto raiz. Este objeto pode ser um objeto mestre para todo o estado do jogo, por exemplo. Outra possibilidade é que você possa armazená-los em uma das classes da coleção Foundation (NSMutableArray, NSMutableSet, NSMutableDictionary).
Quando você for notificado de que seu aplicativo está entrando em segundo plano (applicationDidEnterBackground), será necessário usar o NSKeyedArchiver para salvar todo o estado em um arquivo. Esse arquivo deve estar no diretório de documentos do seu aplicativo. Aqui está um pouco de código para mostrar como isso é feito:
NSArray *docDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [docDirectories objectAtIndex:0];
NSString *saveFile = [docsPath stringByAppendingPathComponent:SAVE_STATE_FILENAME];
[NSKeyedArchiver archiveRootObject:gameState toFile:saveFile;
Quando você detectar que voltou ao primeiro plano, remova o arquivo de salvamento para evitar qualquer confusão na próxima vez em que o aplicativo for iniciado.
Na inicialização do aplicativo, você precisa verificar a existência do arquivo salvo. Se você tiver um, carregue-o assim:
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];
Dependendo do seu design, você pode precisar percorrer o estado do jogo e reconectar quaisquer recursos que não pudessem persistir. Isso realmente depende de como o código do modelo está separado do seu código de renderização.
Nesse ponto, você pode colocar seu jogo em um estado de pausa, dependendo do tipo de jogo que você está criando.
Espero que isso ajude alguém por aí que está tentando implementar a economia de jogos no iPhone.
Como armazenar o estado do jogo é uma pergunta complexa e fortemente dependente de como você configura seu próprio jogo.
Especificamente no iPhone, você precisaria se conectar ao -(void)applicationWillTerminate:
seu UIApplicationDelegate
para capturar quando o aplicativo sairá, da ação do usuário ou de outra forma. Você tem um curto período de tempo para fazer seu trabalho antes que o sistema operacional acabe com seu processo.
Isso dependeria muito de como o seu jogo foi codificado. Você está acompanhando alguns ivars ou algo mais substancial?
Se forem apenas alguns ivars, eu provavelmente os escreveria em um plano de fundo e o carregaria na inicialização.
Se houver mais ivars, você poderá se beneficiar melhor com o CoreData (e / ou salvar seus valores conforme eles mudam, em vez de tentar encaixar tudo na janela fechada).
Da mesma maneira que você o salva quando o usuário bate em um jogo salvo sem sair.
Esta é uma pergunta sobre como salvar o estado do jogo? Ou como fazer algo na saída do aplicativo?
Para o último, a resposta é: appWillTerminate (ou appWillResignActive.) No iOS4 ou posterior, você pode solicitar um tempo extra (Google "iOS-4 solicita tempo extra") se o seu jogo salvo demorar um pouco.
Se você está perguntando como salvar o estado do jogo, sou um grande fã do NSDictionary para armazenar valores facilmente relidos pelo mecanismo do jogo em continuar.
NSMutableDictionary *saveDict = [NSMutableDictionary dictionary];
[saveDict setValue: [NSNumber numberWithInt: currentScore] forKey: @"currentScore"];
// etc...
[saveDict writeToFile: saveFilePath atomically: YES];
Se você quiser, você pode adicionar uma "assinatura" ( ou seja , como MD5 ou similar) para verificar em jogo continuar a ter certeza de que alguém não fez muck com o arquivo para tentar enganar.
Eu diria que não. Salve-o quando fizer sentido para o jogo, não quando o aplicativo estiver saindo. Por exemplo, se este for um jogo baseado em turnos, salve no final de cada turno. Se for um jogo baseado em níveis, salve no final de cada nível. Existem algumas razões para isso:
Aqui está um exemplo de como implementar o protocolo NSCoding para alguns exemplos de classes "map" e "player":
http://deadpanic.com/howtosave
Em seguida, você pode salvar os objetos usando o método NSKeyedArchiver de Dennis.