Как бы вы сохранили состояние игры на выходе для игры для iPhone, написанной на Objective-C?
Как бы вы сохранили состояние игры на выходе для игры для iPhone, написанной на Objective-C?
Ответы:
Вот метод, который я использовал в своих играх.
Во-первых, каждый объект, который необходимо сохранить, должен реализовывать протокол NSCoding. Вы хотите хранить только данные модели и ничего конкретного для текущего процесса. Это означает, что вы не можете сохранять указатели или любые идентификаторы ресурсов, которые ОС предоставляет вам во время выполнения. Для указателей это можно легко исправить, просто убедившись, что вы кодируете объекты, на которые они указывают, вместо самих указателей. Для других ресурсов вам потребуется способ подключения вашего объекта к новому ресурсу во время выполнения.
Во-вторых, убедитесь, что все ваши игровые объекты доступны через один корневой объект. Например, этот объект может быть главным объектом для всего игрового состояния. Другая возможность заключается в том, что вы можете хранить их в одном из классов коллекции 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
поймать , когда приложение будет выходить из действий пользователя или иным образом . У вас есть немного времени, чтобы выполнить свою работу, прежде чем ОС убьет ваш процесс.
Это будет во многом зависеть от того, как ваша игра была закодирована. Вы отслеживаете несколько иваров или что-то более существенное?
Если это всего лишь несколько иваров, я, вероятно, записал бы их в список на фоне и загрузил бы их при запуске.
Если иваров больше, вам лучше использовать CoreData (и / или сохранять их значения по мере их изменения, а не пытаться вписать все в закрывающееся окно).
Точно так же, как вы сохраняете его, когда пользователь поднимает игру, не выходя из нее.
Это вопрос о том, как сохранить состояние игры? Или как сделать что-то на app-exit?
В последнем случае ответ будет следующим: appWillTerminate (или appWillResignActive.) В iOS4 или более поздней версии вы можете запросить дополнительное время (Google «iOS-4 запросить дополнительное время»), если ваша игра-сохранение занимает некоторое время.
Если вы спрашиваете, как вообще сохранить игровое состояние, я большой поклонник NSDictionary для хранения значений, которые легко читаются игровым движком при продолжении.
NSMutableDictionary *saveDict = [NSMutableDictionary dictionary];
[saveDict setValue: [NSNumber numberWithInt: currentScore] forKey: @"currentScore"];
// etc...
[saveDict writeToFile: saveFilePath atomically: YES];
Если вы хотите, вы можете добавить «подпись» ( то есть , например, md5 или аналогичную) для проверки в игре, чтобы убедиться, что кто-то не взломал файл, чтобы попытаться обмануть.
Я бы сказал, нет. Сохраняйте его, когда это имеет смысл для игры, а не когда приложение закрывается. Например, если это пошаговая игра, сохраняйте ее в конце каждого хода. Если это игра, основанная на уровнях, сохраняйте в конце каждого уровня. Есть несколько причин для этого:
Вот пример того, как реализовать протокол NSCoding для некоторых примеров классов «map» и «player»:
http://deadpanic.com/howtosave
Затем вы можете сохранить объекты, используя метод NSKeyedArchiver Дениса.