การจัดเก็บสถานะเกมเมื่อออกจาก iPhone ด้วย Objective-C


คำตอบ:


7

นี่คือวิธีที่ฉันใช้ในเกมของฉัน

ก่อนอื่นวัตถุทุกอย่างที่ต้องคงอยู่จะต้องใช้โปรโตคอล 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


2

วิธีเก็บสถานะเกมเป็นคำถามที่ซับซ้อนซึ่งขึ้นอยู่กับว่าคุณตั้งค่าเกมอย่างไร

บน iPhone โดยเฉพาะคุณจะต้องขอให้-(void)applicationWillTerminate:คุณUIApplicationDelegateจับเมื่อแอปพลิเคชันจะออกจากการกระทำของผู้ใช้หรืออย่างอื่น คุณมีเวลาสั้น ๆ ในการทำงานก่อนที่ระบบปฏิบัติการจะฆ่ากระบวนการของคุณ


2
applicationWillTerminate ใช้งานได้เฉพาะกับแอปพลิเคชั่นที่ไม่รองรับการทำงานหลายอย่างหรือสำหรับ pre-4.0 SDK ควรใช้ applicationDidEnterBackground ด้วยรหัส post-4.0
เดนนิสมันซี

1

ส่วนใหญ่จะขึ้นอยู่กับว่าโค้ดเกมของคุณเป็นอย่างไร คุณกำลังติดตามบาง ivars หรือบางสิ่งบางอย่างยิ่งขึ้น?

หากเป็นเพียงไม่กี่ ivars ฉันอาจจะเขียนพวกมันลงบนพื้นหลังแล้วโหลดตอนเริ่มต้น

หากมี ivars มากกว่านี้คุณอาจจะดีกว่าด้วย CoreData (และ / หรือบันทึกค่าของพวกเขาเมื่อพวกเขาเปลี่ยนแทนที่จะพยายามใส่ทุกอย่างลงในหน้าต่างปิด)


คุณสามารถทำสิ่งต่างๆมากมายได้จริงตามเวลาที่ระบบปฏิบัติการให้คุณปิด ฉันสามารถคงวัตถุเกมไว้ได้ค่อนข้างน้อย (อย่างน้อยสองสามร้อย) โดยใช้วิธีที่ฉันอธิบายไว้ในคำตอบของฉันในเวลานั้น แม้แต่ใน iPod touch 1G ที่ช้า วิธีแก้ปัญหา CoreData อาจทำงานได้ดีขึ้นเมื่อแอพหยุดทำงานทั้งนี้ขึ้นอยู่กับประเภทของเกมที่คุณเล่น แต่จะทำให้การเล่นเกมช้าลง
Dennis Munsie

1

เช่นเดียวกับที่คุณบันทึกเมื่อผู้ใช้กระแทกเกมโดยไม่ต้องออก

คำถามนี้เกี่ยวกับวิธีบันทึกสถานะเกมหรือไม่ หรือวิธีการทำบางสิ่งบางอย่างที่ 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 หรือคล้ายกัน) เพื่อตรวจสอบกับเกมอย่างต่อเนื่องเพื่อให้แน่ใจว่าคนที่ยังไม่ได้ mucked กับแฟ้มที่จะพยายามที่จะโกง


1

ฉันจะบอกว่าไม่ บันทึกเมื่อมันสมเหตุสมผลสำหรับเกมไม่ใช่เมื่อแอพกำลังออก ตัวอย่างเช่นหากเกมนี้เป็นเทิร์นเบสให้บันทึกตอนท้ายของแต่ละเทิร์น หากเป็นเกมที่ใช้เลเวลให้บันทึกตอนท้ายของแต่ละด่าน มีสองเหตุผลสำหรับสิ่งนี้:

  • การใช้งานมือถือไม่แน่นอนมาก ใช่คุณจะได้รับแจ้งจาก iPhone SDK เมื่อแอปปิดอยู่ แต่อาจอยู่ตรงกลางของทุกอย่างและการเปลี่ยนแปลงไม่เพียงแค่ "ออก" เท่านั้น แต่ยังรับสายเรียกรับข้อความ ฯลฯ
  • คุณมีเวลาและทรัพยากรที่ จำกัด ในการปิดเกมของคุณเมื่อออกจากแอพ ส่วนใหญ่นั้นอาจจะถูกใช้เพียงแค่หยุดเกมชั่วคราวและล้างหน่วยความจำ ไม่จำเป็นต้องเพิ่มลงในโหลดนั้นโดยการบันทึกสถานะเกม
  • เกมส่วนใหญ่มีการหยุดตามธรรมชาติที่เหมาะสมสำหรับการบันทึก คุณสามารถใช้ประโยชน์จากการหยุดชั่วคราวเพื่อเก็บสถานะเกมได้อย่างราบรื่นและผู้ใช้จะไม่สังเกตเห็นว่าคุณกำลังใช้ทรัพยากรเพิ่มเติม
  • โดยการบันทึกเพิ่มขึ้นในระหว่างการเล่นเกมจำนวนข้อมูลที่จะบันทึกจะมีขนาดเล็กลงต่อการบันทึก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.