我想在 NSCoder 中使用和存储游戏状态单例,但我发现很难找到使用 NSKeyedArchiver/NSCoder 例程保存和加载其数据的通用状态管理。
我想知道是否有人可以指导我学习一个好的教程,或用作游戏状态单例的通用代码,并在 NSCoder 中保存/加载?
谢谢
我想在 NSCoder 中使用和存储游戏状态单例,但我发现很难找到使用 NSKeyedArchiver/NSCoder 例程保存和加载其数据的通用状态管理。
我想知道是否有人可以指导我学习一个好的教程,或用作游戏状态单例的通用代码,并在 NSCoder 中保存/加载?
谢谢
通过观看 71squared.com 的教程,我已经能够获得一个基本的游戏状态管理器。
我使用来自 CocoaWithLove 的 SynthesizeSingleton.h,并且能够使用 NSCoder / 归档来保存和加载状态。
由于它使用了单例,我可以通过编写来引用它:
GameStateManager *gsm = [GameStateManager sharedGameStateManager];
如下:
// GameStateManager.h file
@interface GameStateManager : NSObject
{
NSMutableArray *listOfPlayers;
}
@property (nonatomic, retain) NSMutableArray *listOfPlayers;
+ (GameStateManager *)sharedGameStateManager;
-(void)loadGameState;
-(void)saveGameState;
// GameStateManager.m
#import "GameStateManager.h"
#import "SynthesizeSingleton.h"
#import "Player.h"
@implementation GameStateManager
SYNTHESIZE_SINGLETON_FOR_CLASS(GameStateManager)
@synthesize listOfPlayers;
#pragma mark - Init
- (id)init
{
self = [super init];
if (self) {
// Initialization code here.
self.listOfPlayers = [NSMutableArray array];
}
return self;
}
#pragma mark - Memory management
-(void) dealloc
{
[super dealloc];
}
#pragma mark - Save/Load
-(void)saveGameState
{
NSLog(@"saveGameState");
// Set up the game state path to the data file that the game state will be save to
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *gameStatePath = [documentsDirectory stringByAppendingPathComponent:@"gameState.dat"];
// Set up the encoder and storage for the game state data
NSMutableData *gameData;
NSKeyedArchiver *encoder;
gameData = [NSMutableData data];
encoder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:gameData];
// Archive the object
[encoder encodeObject:self.listOfPlayers forKey:@"playerObjects"];
// Finish encoding and write to disk
[encoder finishEncoding];
[gameData writeToFile:gameStatePath atomically:YES];
[encoder release];
}
-(void)loadGameState
{
NSLog(@"loadGameState");
// Set up the game state path to the data file that the game state will be save to
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *gameStatePath = [documentsDirectory stringByAppendingPathComponent:@"gameState.dat"];
NSMutableData *gameData;
NSKeyedArchiver *decoder;
gameData = [NSData dataWithContentsOfFile:gameStatePath];
// Check to see if the .dat file exists, and load contents
if (gameData)
{
decoder = [[[NSKeyedUnarchiver alloc] initForReadingWithData:gameData] retain];
self.listOfPlayers = [[[decoder decodeObjectForKey:@"playerObjects"] retain] autorelease];
NSLog(@"Returned %d players", [self.listOfPlayers count]);
for (Player *p in self.listOfPlayers)
{
NSLog(@"p.name = %@", p.fname);
}
// Finished decoding, release
[decoder release];
[decoder autorelease];
} else {
}
}
在我的 Player.h/.m 文件中,我这样做:
@interface Player : NSObject
<NSCoding>
{
NSString *fname;
}
@property(nonatomic,retain) NSString *fname;
// Player.m file
#pragma mark - Encoding
-(id)initWithCoder:(NSCoder *)aDecoder
{
//[self initWithObject:[aDecoder decodeObject];
self = [super init];
if (self) {
// Initialization code here.
self.fname = [aDecoder decodeObjectForKey:@"fname"];
}
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.fname forKey:@"fname"];
}
// ---
我的后续问题是:
1) 我是否打算listOfPlayers
在 GameStateManager 中添加一个?--> 移到一个新问题
2)在我的编码器中,我必须单独存储每个字段,难道不能只存储实际对象本身吗?
3) 对象的编码是否也编码了它的所有子对象?
假设我有一个父类(玩家)和一个子类(武器)。如果我只对 Player 对象进行编码,它是否会自动对所有武器进行编码,因为它们是链接的?
谢谢。