我刚刚了解了 STL 的 i/o 部分,更具体地说是 fstream。虽然我现在可以将我制作的二进制信息和类保存到硬盘,但我不确定如何定义应该如何读取信息。
我从 this 看到了制作文件格式的答案帖子:
Typically you would define a lot of records/structures, such as BITMAPINFOHEADER, and specify in what order they should come, how they should be nestled, and you might need to write a lot of indices and look-up tables. Such files consists of a number of records (maybe nestled), look-up tables, magic words (indicating structure begin, structures end, etc.) and strings in a custom-defined format.
我特别想知道的是如何使用STL 和 C++... 由于该格式仅供游戏使用,因此我认为它会容易得多。格式应该:
- 可遍历(我可以查看它并找到结构的开始,并可能检查它的名称
- 能够在一个文件中保存多个类和数据
- 具有可识别的部分开始和结束:例如文本文件中的空格
- 也许有自己的图标来代表它??
我如何在 C++ 中执行此操作?
最佳答案
确定如何构建保存文件的第一步是确定需要存储哪些信息。据推测,您有一个实体列表,每个实体都有通用信息(可能派生自几个基类之一),例如位置、速度等。
要实现 map 格式,您可以做的最好的事情之一就是为每个类都有一个保存解析器(有些可以从基类的保存解析器派生)。因此,例如,如果您有一个派生自 CBaseNPC 的玩家类,您很可能可以简单地派生自 CBaseNPC,覆盖解析器,调用基类函数,并添加任何其他必要的字段,例如,如果我们有(伪代码):
void CBaseNPC::Save() {
SaveToFile( health );
SaveToFile( armor );
SaveToFile( weapons );
SaveToFile( position );
SaveToFile( angles );
}
然后对于你的玩家类:
void CPlayer::Save() {
CBaseNPC::Save();
SaveToFile( achievement_progress );
}
显然,这只是一个简单的示例,毫无疑问,您的保存解析器将有更多的字段等需要处理。
处理文件本身的结构,您需要担心的主要是定界符,您的主要加载解析器将如何识别每个字段对应的内容?
我想最好的解释方法是举个例子,下面是一个保存文件的简单开始:
Map: {mapname}
Gametime: {gametime}
===Player===
Health: {health}
Armor: {armor}
Weapons: {wep1 (wep1Ammo), wep2 (wep2Ammo), wep3 (wep3Ammo)}
Position: {x, y, z}
Angles: {yaw, pitch, roll} // Could be quaternion instead.
AchievementProgress: {arbritraryData}
===Player===
===NPC-npc_name===
Health: {health}
Armor: {armor}
Weapons: {wep1 (wep1Ammo), wep2 (wep2Ammo), wep3 (wep3Ammo)}
Position: {x, y, z}
Angles: {yaw, pitch, roll} // Could be quaternion instead.
===NPC-npc_name===
===Entity-item_name===
Position: {x, y, z}
Angles: {yaw, pitch, roll}
Model: {modelname}
===Entity-item_name===
这里我们使用“===”字符串作为类参数开始的分隔符,并使用换行符作为每个类内参数的分隔符。
然后构造您的解析器使其读取 map 名称并加载它是一件相对简单的事情。然后将游戏时间设置为保存文件中指定的值。
然后它遍历文件直到找到一个“===”读取它遇到的字符串,并从字典中查找(可能是 std::map
或 std::unordered_map
) 以确定要使用文件中的信息创建(或编辑)的类。一旦确定了类类型,它就可以继续调用该类的 Load()
函数,这将检索包含的所有信息。然后解析器查找“==={遇到的字符串}===”的下一个实例并关闭该类。然后它会按照相同的过程处理遇到的下一个类。
对于这篇文章的篇幅,我深表歉意,我相信它可以变得更简短,而且我可能遗漏了一些东西,我只是随手写下了这篇文章,所以这里可能有错误的地方,但我希望它能让您走上获得可行的保存文件格式的正确道路。 :)
如果您对我的帖子还有什么问题或疑问,请评论,我会尽力及时回答。
关于c++ - 如何使用 STL 在 C++ 中创建游戏保存文件格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6797178/