Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中为基于文本的游戏制作保存文件_Python_Python 3.x_Game Engine - Fatal编程技术网

在Python中为基于文本的游戏制作保存文件

在Python中为基于文本的游戏制作保存文件,python,python-3.x,game-engine,Python,Python 3.x,Game Engine,tl;以下以粗体显示的dr 我目前正在开发一个基于文本的冒险游戏,并且我已经实现了一个基本的保存系统 该过程利用了“pickle”模块。它生成或附加到具有自定义扩展名的文件(实际上是文本文件时)。 引擎会修改玩家的位置,他们的库存,最后一部分会有点奇怪 游戏从一个特殊格式的脚本加载对话框(这里我指的是演员的脚本)。某些对话框会根据特定条件(之前已与他们交谈过、新事件等)进行更改。因此,对于引擎保存的第三个对象,它将所有对话框树保存在其当前位置。与中一样,它将文字脚本保存为当前状态 以下是保存例程

tl;以下以粗体显示的dr

我目前正在开发一个基于文本的冒险游戏,并且我已经实现了一个基本的保存系统

该过程利用了“pickle”模块。它生成或附加到具有自定义扩展名的文件(实际上是文本文件时)。 引擎会修改玩家的位置,他们的库存,最后一部分会有点奇怪

游戏从一个特殊格式的脚本加载对话框(这里我指的是演员的脚本)。某些对话框会根据特定条件(之前已与他们交谈过、新事件等)进行更改。因此,对于引擎保存的第三个对象,它将所有对话框树保存在其当前位置。与中一样,它将文字脚本保存为当前状态

以下是保存例程:

with open('save.devl','wb') as file:
    pickle.dump((current_pos,player_inv,dia_dict),file)
    for room in save_map:
        pickle.dump(room,file)
    file.close()

我的问题是,这个过程会生成一个非常难看、非常冗长的超大文本文件。现在我知道文本文件基本上是我能生成的最小的文件,但我想知道是否有任何方法可以压缩或以其他方式更有效地记录游戏中所有内容的状态。或者,不太可取,但从长远来看更好,只是一种更聪明的方式来保存玩家的数据。

请求了对话框的格式。以下是一个示例:

[Isaac]
a: Hello.|1. I'm Evan.|b|
b: Nice to meet you.|1. Where are you going?\2.Goodbye.|c,closer|
c: My cousin's wedding.|1. Interesting. Where are you from?\2. What do you know about the ship?\3. Goodbye.|e,closer|
closer: See you later.||break|
e: It's the WPT Magnus. Cruise-class zeppelin. Been in service for about three years, I believe.||c|
standing: Hello, again.|1. What do you know about the ship?\2.Goodbye.|e,closer|
括号中的名称是程序如何识别要调用的树。每个字母都是树上一根独立的树枝。这些条把树枝分成三部分:1。角色所说的2。你的回答是允许的3。如果玩家没有回应,玩家随后会被引导到哪里


在本例中,玩家与Isaac交谈后,将从游戏存储在内存中的树副本中删除“a”分支。然后它将永久使用“standing”分支。

Pickle本身有其他协议,这些协议都比默认协议(协议0)更紧凑,默认协议是唯一一个“基于文本”的协议,其他协议是二进制协议

但是,对于这些问题,您很难获得超过50%的文件大小-为了能够增强答案,我们需要更好地了解您正在保存的内容,以及是否有更聪明的方法来保存数据-例如,如果您的几个房间中存在相同的子数据结构,则避免重复该子数据结构。(尽管如果您在游戏中使用对象标识,Pickle应该注意这一点)

也就是说,只需更改pickle.dump调用以包含协议参数,
-1
值相当于“HIGHEST_protocol”,这通常是最有效的:

pickle.dump(room,file, protocol=-1)
(加载pickle根本不需要传递协议)

另外,您可能希望使用Python的zlib接口来压缩pickle数据。这可能会使您的文件大小再减少20-30%——您必须将对file.write、zlib.compress和pickle.dumps的调用链接起来,这样使用一点帮助程序代码就更容易了——您还需要控制文件偏移量,因为zlib不像pickle那样推进文件指针:

import pickle, zlib 

def store_obj(file_, obj):
    compressed = zlib.compress(pickle.dumps(obj, protocol=-1), level=9)
    file_.write(len(compressed).to_bytes(4, "little"))
    file_.write(compressed)

def get_obj(file_):

     obj_size = int.from_bytes(file_.read(4), "little")
     if obj_size == 0:
         return None
     data = zlib.decompress(self.file_.read(obj_size))
     return pickle.loads(data)

您的对话框树的格式是什么?你能举一个合适的例子吗?“现在我知道文本文件基本上是我能生成的最小的文件……”这似乎是一个需要一些支持证据的陈述。我想你会发现这不一定是真的。如果您意识到正在寻找一种高效序列化数据的方法,它可能会帮助您找到解决方案。这可能会提供一些有用的搜索结果。不存储整个对话框树似乎也是一个明显的优化(可能存储某种游标?或条件值?)他不想要资源推荐,他想要一个解决方案!因此,例程会对对象本身进行pickle。我已经为房间、物品、角色等创建了对象类型。因此,保存文件看起来非常混乱,从理论上讲,玩家可以调整一些文本。这里可以看到一个保存文件的示例:(出于某种原因,我无法复制文本)我对对象进行pickle只是因为它更简单,至少引擎当前的工作方式是这样的。我确信要做的一件事是检查任何未勾选的错误。如果真的发生了这种情况,我会抓住它并指责玩家作弊:)Pickle绝对不是一种可以人为编辑的格式,即使在协议的文本版本中也是如此。您应该考虑大小性能或人工可编辑性,在后一种情况下,使用JSON而不是pickle序列化对象。(Json不是所有Python对象类型都自动生成的,您必须调整代码)。这个问题是针对文件大小的。然而,对于一个非常格式化的JSON输出来说,额外的可读性可能会使文件更大,因为它肯定更容易“手工”编辑。我本来打算使用JSON,但pickle更友好,因为我很懒。所以,如果我理解正确的话,我是以一种相对最佳的方式来做这件事的?我看到你使用的主要是文本-压缩解决方案会给你一个小得多的文件。但不可编辑。所以这是你的选择。正如您所看到的,对于可编辑文件,pickle不是傻瓜。