如何为我的游戏编写一个保存/加载系统?


17

我试图找出一种方法来为我的游戏使用C ++编写保存/加载系统。截至目前,我正在使用二进制标志来完成所有操作。任何人都有其他方法的线索吗?我不介意使用二进制文件,但我想知道我的选择。我还想要一种可以很容易地检查一个事件是否完成以决定某些事情的东西(该游戏中的许多物品系统取决于玩家的完成或未完成)在整个游戏过程中)。


1
实际上,看了之后,对我来说,坚持使用Python进行项目可能会更好。我将Panda3D用作游戏引擎,并且python版本更加完善。这样,我可能会在python中更快地开发。另外,python有一个内置的序列化类,称为pickle,这为我省去了编写代码的麻烦。
sonicbhoc

Answers:


5

序列化是解决问题的方法,对于状态检查,可以在反序列化方法中使用逻辑来做到这一点。


我在这里(parashift.com/c++-faq-lite/serialization.html)对此进行了阅读,它看起来非常有趣。我从来没有真正处理过序列化,所以对我来说这将是一个很好的学习经历。谢谢!
sonicbhoc

没问题!我也在为游戏使用序列化(尽管在C#中)。祝好运!
ThatsGobbles

4
请记住:如果要序列化,请始终先存储版本号,然后再读回该版本号。这样,您可以通过提供(某些)向后兼容性来优雅地处理对savegame格式的重大更改。
LearnCocos2D 2010年

4
在开发过程中,我也强烈建议您将文件写入人类可读的格式。也许像JSON或XML。更容易查看是否已保存所需的所有内容,也更容易调整已写入文件中的数据(用于测试或将文件写入磁盘后进行修复)。
bummzack

5

我已经研究了DOOM源代码。我会告诉你那里的情况。

D_DoomMain包含所有打开/保存/加载功能,以及许多其他功能。就像文件开头所说的那样,

// DESCRIPTION:
//      DOOM main program (D_DoomMain) and game loop (D_DoomLoop),
//      plus functions to determine game mode (shareware, registered),
//      parse command line parameters, configure game parameters (turbo),
//      and call the startup functions.

基本上,整个文件M_CheckParm从头到尾都充满了。这就是D_DoomLoop的组成。这是一个巨大的循环(大约1000-2000行长)。

由于您的问题是“我怎么写?” 我将粘贴来自D_DoomMain的一些指向gameaves的代码:

在循环的最后,这是使用这些东西的语句。

   p = M_CheckParm ("-loadgame");
   if (p && p < myargc-1)
   {
       if (M_CheckParm("-cdrom"))
           sprintf(file, "c:\\doomdata\\"SAVEGAMENAME"%c.dsg",myargv[p+1][0]);
       else
           sprintf(file, SAVEGAMENAME"%c.dsg",myargv[p+1][0]);
       G_LoadGame (file);
   }


   if ( gameaction != ga_loadgame )
   {
       if (autostart || netgame)
           G_InitNew (startskill, startepisode, startmap);
       else
           D_StartTitle ();                // start up intro loop

   }

   D_DoomLoop ();  // never returns

这是访问字符串的函数,您会发现这些字符串分散在整个代码中:

void M_ReadSaveStrings(void)
{
   int             handle;
   int             count;
   int             i;
   char    name[256];

   for (i = 0;i < load_end;i++)
   {
       if (M_CheckParm("-cdrom"))
           sprintf(name,"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",i);
       else
           sprintf(name,SAVEGAMENAME"%d.dsg",i);

       handle = open (name, O_RDONLY | 0, 0666);
       if (handle == -1)
       {
           strcpy(&savegamestrings[i][0],EMPTYSTRING);
           LoadMenu[i].status = 0;
           continue;
       }
       count = read (handle, &savegamestrings[i], SAVESTRINGSIZE);
       close (handle);
       LoadMenu[i].status = 1;
   }
}

您还拥有一个名为p_savegame.c的文件,该文件中的内容将保存所有与用户相关的数据(您拥有的武器,处于哪个级别等)。

最后,您将获得可以将保存游戏数据加载到游戏场景中的文件,可以说是最复杂的文件,因为它还可以加载其他所有内容。该用户名为p_setup.c,位于同一目录中。

对我来说,cat将所有这些都存储到文本缓冲区中并将pipe该文本存储sendmail到我自己的电子邮件地址中非常有效。这样一来,我可以在一天中的特殊时刻通读它,并在需要查找“ DOOM如何加载游戏”之类的内容时使用“查找”。该代码是很好的注释。



-1

我+1:建议使用XML / JSON构建保存游戏。这样,您就准备好使保存基于“云”。或者至少,您将拥有一个结构,可用于可能涉及网络的未来项目。只要文件的存储方式不易阅读,它们就会给您带来很多好处。像指标!万岁


1
云存储只是意味着您在线存储保存。您可以使用任何文件格式来实现。

我知道。但是出于沟通目的,最好使用易于传输的内容进行结构化。
Phil

如果您的游戏与自己的保存文件格式不兼容,那么您遇到的问题要比“轻松转移”
大得多

XML和JSON保存很容易被篡改(= cheat)。作为开发人员,您可能会满意,也可能不满意。
Trang Oul
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.