在哪里可以找到 Objective C 的通用游戏状态单例?

发布于 2024-12-16 19:09:51 字数 159 浏览 2 评论 0原文

我想在 NSCoder 中使用和存储游戏状态单例,但我发现很难找到使用 NSKeyedArchiver/NSCoder 例程保存和加载其数据的通用状态管理。

我想知道是否有人可以指导我一个好的教程,或者用作游戏状态单例的通用代码,并在 NSCoder 中保存/加载?

谢谢

I'm wanting to use, and store a game state singleton inside NSCoder, but I am finding it quite difficult to find a generic state management that saves and loads its data using the NSKeyedArchiver/NSCoder routines.

I'm wondering if someone can direct me to a good tutorial, or generic code for use as a game state singleton, with it saving/loading in NSCoder?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最初的梦 2024-12-23 19:09:51

我已经能够通过观看 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)一个对象的编码是否也会对其所有子对象进行编码?

假设我有一个父类(玩家)和一个子类(武器)。如果我只对玩家对象进行编码,它是否会自动对所有武器进行编码,因为它们是链接的?

谢谢。

I've been able to get a basic game state manager working from watching tutorials from 71squared.com

I use the SynthesizeSingleton.h from CocoaWithLove and am able to save and load states using NSCoder / archiving.

As it uses the singelton, I can reference it by writing:

GameStateManager *gsm = [GameStateManager sharedGameStateManager];

As below:

// 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 {


    }

}

In my Player.h/.m file I do this:

@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"];
}

// ---

My follow-up questions are:

1) Am I meant to put a listOfPlayers in the GameStateManager?
--> Moved to a new question

2) In my encoder, I have to store each field individually, is it not possible to just store the actual object itself?

3) Does encoding of an object also encode all its children?

Lets say I have a Parent class (Player) and a Child class (Weapons). If I encode the Player object only, will it encode all the Weapons too automatically because they are linked?

Thanks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文