Objective-C ile yazılmış bir iPhone oyunu için oyun durumunuzu çıkışta nasıl saklarsınız?
Objective-C ile yazılmış bir iPhone oyunu için oyun durumunuzu çıkışta nasıl saklarsınız?
Yanıtlar:
İşte oyunlarımda kullandığım yöntem.
İlk olarak, kalıcı olması gereken her nesne NSCoding protokolünü uygulamalıdır. Sadece model verilerinizi saklamak istiyorsunuz ve mevcut işleme özgü bir şey yok. Bu, işletim sisteminin size çalışma zamanında verdiği işaretçileri veya kaynak kimliklerini kaldıramayacağınız anlamına gelir. İşaretçiler için, işaretçilerin kendileri yerine işaret ettikleri nesneleri kodladığınızdan emin olarak bunu kolayca düzeltebilirsiniz. Diğer kaynaklar için, çalışma zamanında nesnenizi yeni kaynağa bağlamanın bir yoluna ihtiyacınız olacaktır.
İkinci olarak, tüm oyun nesnelerinize tek bir kök nesne üzerinden erişilebildiğinden emin olun. Bu nesne, örneğin tüm oyun durumu için bir ana nesne olabilir. Başka bir olasılık, bunları Foundation koleksiyon sınıflarından birinde (NSMutableArray, NSMutableSet, NSMutableDictionary) saklayabilmenizdir.
Uygulamanızın arka plana geçtiğini bildirdiğinizde (applicationDidEnterBackground), tüm durumu bir dosyaya kaydetmek için NSKeyedArchiver kullanmanız gerekir. Bu dosya, uygulamanızın belgeler dizininde olmalıdır. İşte bunun nasıl yapıldığını göstermek için biraz kod:
NSArray *docDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [docDirectories objectAtIndex:0];
NSString *saveFile = [docsPath stringByAppendingPathComponent:SAVE_STATE_FILENAME];
[NSKeyedArchiver archiveRootObject:gameState toFile:saveFile;
Ön plana geri döndüğünüzü algıladığınızda, uygulamanızın bir sonraki açılışında karışıklığı önlemek için kaydetme dosyasını kaldırmanız gerekir.
Uygulama başlatıldığında, kayıt dosyasının varlığını kontrol etmeniz gerekir. Eğer bir tane varsa, böyle yüklersiniz:
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];
Tasarımınıza bağlı olarak, oyun durumunu gözden geçirmeniz ve devam edemediğiniz kaynakları yeniden bağlamanız gerekebilir. Bu gerçekten, model kodunuzun oluşturma kodunuzdan ne kadar temiz ayrıldığına bağlıdır.
Bu noktada, ne tür bir oyun yaptığınıza bağlı olarak oyununuzu duraklatılmış bir duruma getirmek isteyebilirsiniz.
Umarım bu, iPhone'da oyun tasarrufu yapmaya çalışan başka birine yardımcı olur.
Oyun durumunun depolanması, oyununuzu nasıl ayarladığınıza büyük ölçüde bağlı olan karmaşık bir sorudur.
Özellikle iPhone'da , uygulamanın ne zaman çıkacağını, kullanıcı işleminden veya başka bir şekilde yakalamak -(void)applicationWillTerminate:
için içine girmeniz UIApplicationDelegate
gerekir. Yine de işletim sistemi sürecinizi öldürmeden önce işinizi yapmak için kısa bir süreniz vardır.
Bu büyük ölçüde oyununuzun nasıl kodlandığına bağlı olacaktır. Birkaç ivar veya daha önemli bir şey mi takip ediyorsunuz?
Sadece birkaç ivarsa, onları muhtemelen arka planda bir plist'e yazar ve başlangıçta yüklerim.
Daha fazla ivar varsa, CoreData ile daha iyi olabilirsiniz (ve / veya her şeyi kapat penceresine sığdırmak yerine değiştikçe değerlerini kaydedebilirsiniz).
Aynı şekilde, kullanıcı bir kaydetme oyununu çıkmadan çıkardığında kaydettiğiniz gibi kaydedin.
Bu soru oyun durumunun nasıl kaydedileceği ile ilgili mi? Veya uygulama çıkışında bir şey nasıl yapılır?
İkincisi için cevap şudur: appWillTerminate (veya appWillResignActive.) İOS4 veya sonraki bir sürümde, kaydetme oyununuz biraz zaman alıyorsa ek süre isteyebilirsiniz (Google "iOS-4 ek süre isteyin").
Oyun durumunu nasıl kaydedeceğinizi soruyorsanız, devam eden oyun motoru tarafından kolayca okunabilen değerleri saklamak için NSDictionary büyük bir hayranıyım.
NSMutableDictionary *saveDict = [NSMutableDictionary dictionary];
[saveDict setValue: [NSNumber numberWithInt: currentScore] forKey: @"currentScore"];
// etc...
[saveDict writeToFile: saveFilePath atomically: YES];
İsterseniz , birisinin hile yapmaya çalışmak için dosyayla uğraşmadığından emin olmak için oyunun devam ettiğini doğrulamak için bir "imza" ( yani md5 veya benzeri gibi) ekleyebilirsiniz.
Yapma derdim. Uygulamadan çıkarken değil, oyun için anlamlı olduğunda kaydedin. Örneğin, bu sıra tabanlı bir oyunsa, her turun sonunda kaydedin. Seviye tabanlı bir oyunsa, her seviyenin sonunda kaydedin. Bunun birkaç nedeni var:
Bazı örnek "map" ve "player" sınıfları için NSCoding protokolünün nasıl uygulanacağına ilişkin bir örnek:
http://deadpanic.com/howtosave
Sonra nesneleri Dennis'in NSKeyedArchiver yöntemini kullanarak kaydedebilirsiniz.