首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C保存游戏状态,减少传递的变量

C保存游戏状态,减少传递的变量
EN

Stack Overflow用户
提问于 2020-03-06 12:14:06
回答 1查看 413关注 0票数 1

我一直在想,是否有一种方法可以节省游戏状态,但以透明的方式进行。这不是一个关于实际保存的问题(我知道如何保存文件等等),而是以一种清晰、简单和可理解的方式编写它。

到目前为止,我已经提出了三个想法(记住,我希望它可以是一个函数,或者像savegame()这样简单的东西),没有一个是完美的:

  1. 将我想要保存的所有变量放入结构中,如:

代码语言:javascript
复制
struct state{
    int hp;
    pos position;
    int x;
    int y;
    ...
};
...
if(savegame==1) {
    state game;
    game.hp=hp;
    game.position=position;
    game.x=x;
    game.y=y;
    ...
    savegame(game);
}

正如你所看到的,它看起来不太好,只需要这么多行来保存:如果我想保存40个变量呢?如果我想在代码中保存5-6个位置怎么办?

  1. 使我的函数只要是蛇(这就给了加载它的问题,例如,我还放了一个loadgame函数):

代码语言:javascript
复制
void savegame(int hp, pos position, int x, int y,...) // too long
{ ... }
void loadgame(int &hp, pos &position, int &x, int &y,...) // too long
{ ... }
...
int main()
{
    ...
    savegame(hp, pos, x, y, ...) // too long
    ...
    loadgame(hp, pos, x, y, ...) // too long
}

再说一遍,如果里面有40个变量(我也想像5-6次那样调用savegame或loadgame ),那么每个代码就需要4行代码(我只是跳过一个把它放在一行中的想法)。

  1. 以包含游戏状态的struct启动我的程序,并进行所有计算,实际上是在该结构

上的所有游戏。

代码语言:javascript
复制
struct gamestate{
    int hp;
    pos position;
    int x;
    int y;
}
...
int main()
{
    struct gamestate s;
    s.x++;
    ...
}

但是这导致了一个问题,每次我做计算时,我都不得不在乞讨时加上这个's‘。

结论:

我的想法是可能改变第二个选择,以减少savegame(...)的每一个调用;到简单的savegame();,有办法做到这一点吗?无define

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-06 16:47:33

下面是一种动态的方法来执行类似于您在第一个选项中描述的事情,即使用指针来跟踪游戏状态,但也可以存储和恢复二进制文件中的数据.

下面的.c和.h文件说明了这样一种想法,即可以使用一个复合结构,即一个包含多个其他结构的复合结构,该结构在任何时候都包含程序中表示状态的所有值。这很容易通过一个函数传递,只有很少的参数(原型例子)。作为char *GetState(state * in,const char *filespec);char *SetState(state *out,const char *filespec),这反过来会将结构的内容写入/读出二进制缓冲区。我使用此方法在文件中存储和检索多组状态数据。

注意,这些结构有随机字段,您当然会根据需要修改这些字段,但是您可以传递一个指向所有状态数据的指针值,该值指向状态日期被更新或需要存储的每个函数。

so_SaveGameState.c

代码语言:javascript
复制
    #include <so_SaveGameState.h>

    unsigned char *pByteA;

    GAME_STATE game = {{{"jim", "C:\\ico1.ico", {10, 120, 3}}, {"joe", "C:\\ico2.ico", {80, 10, -5}},{"larry", "C:\\ico3.ico", {15, -45, -45}},{"sue", "C:\\ico4.ico", {-100, -45, 45}}}, ENVR_3}; 
    GAME_STATE *pGame = NULL;

    int main(void)
    {
        pGame = &game;//point to populated memory


        printf("Player 3 position\nx = %d\ny = %d\nz = %d\n", game.plyr[2].pos.x, game.plyr[2].pos.y, game.plyr[2].pos.z);
        //example function that changes game state
        UpdatePlayerPosition(&pGame, 2);
        printf("Player 3 position\nx = %d\ny = %d\nz = %d\n", game.plyr[2].pos.x, game.plyr[2].pos.y, game.plyr[2].pos.z);
        UpdatePlayerPosition(&pGame, 2);
        printf("Player 3 position\nx = %d\ny = %d\nz = %d\n", game.plyr[2].pos.x, game.plyr[2].pos.y, game.plyr[2].pos.z);
        UpdatePlayerPosition(&pGame, 2);
        printf("Player 3 position\nx = %d\ny = %d\nz = %d\n", game.plyr[2].pos.x, game.plyr[2].pos.y, game.plyr[2].pos.z);
        //prepare an instance of game state for storeing
        (const GAME_STATE *)pByteA = &game;
        int len1 = sizeof(game);
        BOOL status = storeState("C:\\tempextract\\binFileStruct.bin", pByteA, len1);

        //recover a stored state
        unsigned char *buf = recoverState("C:\\tempextract\\binFileStruct.bin");
        GAME_STATE *game_2 = (GAME_STATE *)buf;

        free(game_2);
        return 0;
    }

    unsigned char * recoverState(const char *filespec)
    {
       size_t sz = 0;
       int n = 0;
       unsigned char *binBuf = NULL;
        FILE *fp = fopen(filespec, "rb");
        if(fp)
        {
            fseek(fp, 0L, SEEK_END);
            sz = ftell(fp);
            fseek(fp, 0L, SEEK_SET);
            rewind(fp);

             binBuf = calloc(sz, sizeof(*binBuf));
            n = fread(binBuf, sizeof(unsigned char), sz, fp);
            fclose(fp);
        }
        if(n == sz)
        {
            return binBuf;
        }
        else
        {
            return NULL;
        }
    }

    int storeState(const char *filespec, const unsigned char *buf, size_t sz)
    {
        int count = 0;
        FILE *fp = fopen(filespec, "wb");
        if(fp)
        {
            count = fwrite(buf, sizeof(unsigned char), sz, fp);
            fclose(fp);
        }
        return (count == sz) ? 1 : 0;
    }

    void UpdatePlayerPosition(GAME_STATE **game, int player)
    {
        static int x=0, y=0, z=0;

        static BOOL toggle = TRUE;

        toggle = (toggle == 1) ? -1 : 1;

        srand(clock());
        //using fake assignment here
        //i.e. you would have other criteria to set actual position
        x += toggle * rand()%300;
        y += toggle * rand()%300;
        z += toggle * rand()%300;

        (*game)->plyr[player].pos.x = x;
        (*game)->plyr[player].pos.y = y;
        (*game)->plyr[player].pos.y = z;
    }

so_StoreGameState.h

代码语言:javascript
复制
    typedef enum {//environment
        ENVR_1,  //bad weather
        ENVR_2,  //hill
        ENVR_3,  //pit
        ENVR_4,  //angry birds
        ENVR_5,  //enemy guard
        MAX_OBST
    }ENVR_TYPE;

    typedef struct {
        int x;
        int y;
        int z;
    }POS;

    typedef struct {
        ENVR_TYPE envir;
        //...
    }ENVIR;

    typedef struct {
        char name[20];
        char iconFile[260];
        POS pos;
        //...
    }PLAYER;

    typedef struct {
        PLAYER plyr[4];
        ENVIR env;
        //...
    }GAME_STATE;

    extern GAME_STATE game;

    unsigned char * recoverState(const char *filespec);
    int storeState(const char *filespec, const unsigned char *buf, size_t sz);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60563865

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档