【问题标题】:Where can I find a generic game state singleton for Objective C?我在哪里可以找到 Objective C 的通用游戏状态单例?
【发布时间】:2023-03-04 19:33:01
【问题描述】:

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

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

谢谢

【问题讨论】:

    标签: objective-c save nscoding


    【解决方案1】:

    通过观看 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) 我是否打算在 GameStateManager 中添加 listOfPlayers? --> 转到一个新问题

    2) 在我的编码器中,我必须单独存储每个字段,不能只存储实际对象本身吗?

    3) 对象的编码是否也编码其所有子对象?

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

    谢谢。

    【讨论】:

    • 将您的后续问题作为新问题提出,这里没有人回答它们!
    • 哦,抱歉,我不知道。我的错!
    • 我发现你必须对你想要存储的任何东西进行编码,不管它是否被继承。
    猜你喜欢
    • 1970-01-01
    • 2021-12-02
    • 2010-11-15
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    • 2011-12-31
    • 1970-01-01
    相关资源
    最近更新 更多