Objective-C를 사용하여 iPhone 종료시 게임 상태 저장


답변:


7

게임에서 사용한 방법은 다음과 같습니다.

먼저 유지해야하는 모든 개체는 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에서 게임 저장을 구현하려는 다른 누군가를 도울 수 있기를 바랍니다.


2

게임 상태를 저장하는 방법은 게임 자체를 설정하는 방법에 크게 의존하는 복잡한 질문입니다.

iPhone에서는 구체적 으로 사용자 작업 또는 기타 방법으로 응용 프로그램이 종료되는 시점 -(void)applicationWillTerminate:을 파악 UIApplicationDelegate하기 위해 연결해야합니다 . 그러나 OS가 프로세스를 종료하기 전에 작업을 수행 할 시간이 짧습니다.


2
applicationWillTerminate는 멀티 태스킹을 지원하지 않는 응용 프로그램 또는 4.0 이전 SDK에 대해서만 작동합니다. 4.0 이후 코드와 함께 applicationDidEnterBackground를 사용하는 것이 좋습니다.
데니스 먼지

1

게임 코딩 방법에 따라 크게 달라집니다. 당신은 몇 가지 ivars 또는 더 중요한 것을 추적하고 있습니까?

ivar가 몇 개인 경우 배경에 plist에 작성하고 시작시로드합니다.

ivar이 더 많으면 CoreData를 사용하는 것이 좋습니다 (또는 모든 것을 닫힌 창에 맞추려고하는 대신 값이 변경되면 저장).


OS가 종료하는 시간으로 실제로 많은 작업을 수행 할 수 있습니다. 나는 그 시간에 내 대답에 설명 된 방법을 사용하여 상당히 많은 게임 객체 (적어도 수백 개)를 유지할 수있었습니다. 느린 1G iPod touch에서도. 게임 유형에 따라 CoreData 솔루션은 앱이 종료 될 때 더 잘 작동하지만 게임 플레이 속도가 느려질 수 있습니다.
데니스 먼지

1

사용자가 게임을 종료하지 않고 충돌 할 때 저장하는 것과 같은 방법입니다.

게임 상태를 저장하는 방법에 대한이 질문입니까? 또는 앱 종료시 무언가를 수행하는 방법은 무엇입니까?

후자의 경우 대답은 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 또는 이와 유사한 것)을 추가하여 게임에서 누군가가 치트를 시도하기 위해 파일에 푹 빠지지 않았는지 계속 확인할 수 있습니다.


1

나는 말하지 않을 것입니다. 앱이 종료 될 때가 아니라 게임에 적합 할 때 저장하십시오. 예를 들어, 이것이 턴 기반 게임 인 경우 각 턴이 끝날 때 저장하십시오. 레벨 기반 게임 인 경우 각 레벨의 끝에 저장하십시오. 이에 대한 몇 가지 이유가 있습니다.

  • 모바일 사용은 매우 예측할 수 없습니다. 예, 앱이 닫힐 때 iPhone SDK에 알림이 표시되지만 중간에있을 수 있으며 전환은 "종료"가 아니라 전화 수신, 문자 수신 등입니다.
  • 앱 종료시 게임을 종료하는 데 시간과 리소스가 매우 제한되어 있습니다. 대부분의 경우 게임을 일시 중지하고 메모리를 정리하면 소비됩니다. 게임 상태를 저장하여 해당로드에 추가 할 필요가 없습니다.
  • 대부분의 게임에는 자연스럽게 일시 정지되어 저장에 적합합니다. 이러한 일시 중지를 활용하여 게임 상태를 완벽하게 저장할 수 있으며 사용자는 추가 리소스를 소비하고 있음을 알 수 없습니다.
  • 게임을하는 동안 점진적으로 저장하면 저장되는 데이터의 양이 저장마다 줄어 듭니다.

1

다음은 일부 "map"및 "player"클래스에 대해 NSCoding 프로토콜을 구현하는 방법에 대한 예입니다.

http://deadpanic.com/howtosave

그런 다음 Dennis의 NSKeyedArchiver 방법을 사용하여 객체를 저장할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.