【发布时间】:2018-05-03 08:57:36
【问题描述】:
我正在使用 python 3.6 开发游戏,我希望在其多人游戏版本中将由客户端(玩家)修改的服务器对象发送到我想将它们序列化以进行传输的服务器。我在我的对象中使用 pygame 和因此 pygame.Surface
我有这种结构的对象:
class Cargo(Bateau):
dictCargos = dict()
def __init__(self, map, nom, pos, armateur=None):
Bateau.__init__(self, map, nom, armateur, pos)
self.surface = pygame.image.load(f"images/{self.nom}.png").convert_alpha()
self.rect = self.map.blit(self.surface, self.pos)
...
Cargo.dictCargos[self.nom] = self
当我序列化另一个没有 pygame 实例的对象时,没关系 但是对于上述对象,我会收到以下错误消息:
import pickle as pickle
pickle.dump(Cargo.dictCargos, open('file2.pkl', 'wb'), protocol=pickle.HIGHEST_PROTOCOL)
Traceback (most recent call last):
File "./pytransit.py", line 182, in <module>
encreG(joueur, event)
File "/home/patrick/Bureau/PyTransit/modulesJeu/tests.py", line 25, in encreG
pickle.dump(Cargo.dictCargos, open('file2.pkl', 'wb'), protocol=pickle.HIGHEST_PROTOCOL)
TypeError: can't pickle pygame.Surface objects
您知道如何将这些项目传输到服务器吗?或者绕过这个泡菜限制?
如果我想保存一个零件也会出现同样的问题,所以保存这些对象
【问题讨论】:
-
由于您无法对 Surface 对象进行腌制,因此您需要找到一种方法在腌制之前将其移除并在之后重新创建它们。为此,我建议您查看
pickle文档中的Handling Stateful Objects。我过去用这个来deal with file logging handlers,和你的问题很相似。 -
您能告诉我们您为什么要发送表面吗?你的游戏中到底发生了什么?这个问题听起来有点像XY problem,可能有更好的方法来实现你想要的。另外请注意,从不受信任的来源中提取数据存在巨大的安全风险,因此不应在多人游戏中使用 pickle。
-
"BTW" 的意思是“顺便说一句”,如果您在评论中写上@username,用户将在顶部栏中看到红色的小新评论图标。我只看到了你以前的 cmets,因为我还打开了这个标签。
-
如果你只发送位置和其他可以用json模块序列化的简单数据类型,你可以使用JSON格式。我会避免发送表面,因为它们可能非常大。