Мне удалось заставить работать основного менеджера состояний игры, просмотрев учебники с 71squared.com
Я использую SynthesizeSingleton.h из CocoaWithLove и могу сохранять и загружать состояния, используя NSCoder / archiving.
Поскольку он использует сингелтон, я могу сослаться на него, написав:
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, будет ли он автоматически кодировать все Оружие, потому что они связаны?
Спасибо.