我试图找出一种方法来为我的游戏使用C ++编写保存/加载系统。截至目前,我正在使用二进制标志来完成所有操作。任何人都有其他方法的线索吗?我不介意使用二进制文件,但我想知道我的选择。我还想要一种可以很容易地检查一个事件是否完成以决定某些事情的东西(该游戏中的许多物品系统取决于玩家的完成或未完成)在整个游戏过程中)。
我试图找出一种方法来为我的游戏使用C ++编写保存/加载系统。截至目前,我正在使用二进制标志来完成所有操作。任何人都有其他方法的线索吗?我不介意使用二进制文件,但我想知道我的选择。我还想要一种可以很容易地检查一个事件是否完成以决定某些事情的东西(该游戏中的许多物品系统取决于玩家的完成或未完成)在整个游戏过程中)。
Answers:
序列化是解决问题的方法,对于状态检查,可以在反序列化方法中使用逻辑来做到这一点。
我已经研究了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如何加载游戏”之类的内容时使用“查找”。该代码是很好的注释。