Jak zapisałbyś swój stan gry przy wyjściu dla gry na iPhone'a napisanej w Objective-C?
źródło
Jak zapisałbyś swój stan gry przy wyjściu dla gry na iPhone'a napisanej w Objective-C?
Oto metoda, której użyłem w swoich grach.
Po pierwsze, każdy obiekt, który musi zostać utrwalony, musi implementować protokół NSCoding. Chcesz tylko przechowywać dane modelu i nic konkretnego dla bieżącego procesu. Oznacza to, że nie można zachować wskaźników ani żadnych identyfikatorów zasobów, które system operacyjny podaje w czasie wykonywania. W przypadku wskaźników możesz to łatwo naprawić, po prostu upewniając się, że kodujesz obiekty, na które wskazują, zamiast samych wskaźników. W przypadku innych zasobów potrzebny będzie sposób na podłączenie obiektu do nowego zasobu w czasie wykonywania.
Po drugie, upewnij się, że do wszystkich twoich obiektów gry można uzyskać dostęp za pośrednictwem jednego obiektu głównego. Ten obiekt może być na przykład obiektem głównym dla całego stanu gry. Inną możliwością jest przechowywanie ich w jednej z klas kolekcji Foundation (NSMutableArray, NSMutableSet, NSMutableDictionary).
Po wyświetleniu powiadomienia o przeniesieniu aplikacji w tło (applicationDidEnterBackground) konieczne będzie użycie NSKeyedArchiver w celu zapisania całego stanu w pliku. Ten plik powinien znajdować się w katalogu dokumentów aplikacji. Oto trochę kodu pokazującego, jak to się robi:
NSArray *docDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [docDirectories objectAtIndex:0];
NSString *saveFile = [docsPath stringByAppendingPathComponent:SAVE_STATE_FILENAME];
[NSKeyedArchiver archiveRootObject:gameState toFile:saveFile;
Po wykryciu, że wróciłeś na pierwszy plan, usuń plik składowania, aby uniknąć nieporozumień przy następnym uruchomieniu aplikacji.
Podczas uruchamiania aplikacji należy sprawdzić, czy istnieje plik składowania. Jeśli masz, ładujesz go w następujący sposób:
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];
W zależności od projektu może być konieczne przejście przez stan gry i ponowne połączenie wszystkich zasobów, których nie można było zachować. To naprawdę zależy od tego, jak czysto oddzielony jest Twój kod modelu od kodu renderującego.
W tym momencie możesz chcieć ustawić grę w stan pauzy, w zależności od rodzaju tworzonej gry.
Mam nadzieję, że pomoże to komuś innemu, kto próbuje wdrożyć zapisywanie gier na iPhonie.
Jak zapisać stan gry to złożone pytanie, które w dużej mierze zależy od konfiguracji samej gry.
Na iPhone specjalnie, by po prostu trzeba się podłączyć do -(void)applicationWillTerminate:
w swojej UIApplicationDelegate
złapać, gdy aplikacja wyjdzie z działania użytkownika lub w inny sposób. Masz jednak niewiele czasu na wykonanie pracy, zanim system operacyjny zabije Twój proces.
Zależy to w dużej mierze od sposobu zakodowania gry. Czy śledzisz kilka ivarów czy coś bardziej znaczącego?
Jeśli to tylko kilka ivarów, prawdopodobnie zapisałbym je na liście w tle i załadowałbym przy starcie.
Jeśli jest więcej ivarów, lepiej może być z CoreData (i / lub zapisywać ich wartości, gdy się zmieniają, zamiast próbować dopasować wszystko do zamkniętego okna).
źródło
W ten sam sposób, w jaki zapisujesz, gdy użytkownik uderzy w grę zapisu bez wychodzenia.
Czy to pytanie o to, jak zapisać stan gry? Lub jak zrobić coś przy wyjściu z aplikacji?
W przypadku tego ostatniego odpowiedź brzmi: appWillTerminate (lub appWillResignActive.) W systemie iOS4 lub nowszym możesz poprosić o dodatkowy czas (Google „iOS-4 żąda dodatkowego czasu”), jeśli gra wymaga czasu.
Jeśli pytasz, jak w ogóle zapisać stan gry, jestem wielkim fanem NSDictionary do przechowywania wartości łatwo ponownie odczytanych przez silnik gry w dalszym ciągu.
Jeśli chcesz, możesz dodać „podpis” ( np. Md5 lub podobny), aby zweryfikować w grze, aby upewnić się, że ktoś nie zepsuł się z plikiem, aby spróbować oszukać.
źródło
Powiedziałbym nie. Zapisz go, gdy ma to sens dla gry, a nie kiedy aplikacja się kończy. Na przykład, jeśli jest to gra turowa, zapisz na końcu każdej tury. Jeśli jest to gra oparta na poziomie, zapisz na końcu każdego poziomu. Jest kilka powodów:
źródło
Oto przykład implementacji protokołu NSCoding dla niektórych przykładowych klas „map” i „player”:
http://deadpanic.com/howtosave
Następnie możesz zapisać obiekty za pomocą metody Dennis 'NSKeyedArchiver.
źródło