Где я могу найти общий синглтон состояния игры для Objective C? - PullRequest
1 голос
/ 16 ноября 2011

Я хочу использовать и сохранить синглтон состояния игры в NSCoder, но мне довольно сложно найти общее управление состоянием, которое сохраняет и загружает свои данные с помощью процедур NSKeyedArchiver / NSCoder.

Мне интересно, может ли кто-нибудь направить меня к хорошему учебнику или универсальному коду для использования в качестве синглтона состояния игры с его сохранением / загрузкой в ​​NSCoder?

Спасибо

1 Ответ

0 голосов
/ 16 ноября 2011

Мне удалось заставить работать основного менеджера состояний игры, просмотрев учебники с 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, будет ли он автоматически кодировать все Оружие, потому что они связаны?

Спасибо.

...