为了轻松保存游戏的游戏状态,我倾向于序列化包含所有游戏实体(a.k.a. actors)的game
对象。
我遇到的一个常见问题是你不能挑剔pygame surfaces,所以如果你的演员类看起来像这样:
class Actor(object):
def __init__(self, **kwargs):
self._image = kwargs['image']
self.pos = kwargs['pos']
...
def act(self):
...
def draw(self, surface):
surface.blit(self._image, self.pos)
你不能只用python pickle/cpickle模块来腌制它。
如何解决这个问题?
答案 0 :(得分:2)
解决方案不是尝试序列化曲面,而是将其从游戏/游戏实体中删除,并使用lazy loading之类的技术,例如恢复游戏状态后再次获得它们。
因此,不是将表面直接传递给实体,而是传递一个负责存储/检索表面的对象:
class Actor(object):
def __init__(self, **kwargs):
self._image_getter = kwargs['image_getter']
self.pos = kwargs['pos']
...
def draw(self, surface):
surface.blit(self._image_getter(), self.pos)
image getter
可能如下所示:
class SurfaceCapsule (object):
def __init__(self, resource_manager, key):
self._res = resource_manager
self._key = key
def __call__(self):
return self._res[self._key]
请注意,我在这里使用了一个类,因为方法本身也不可用。
而不是像这样创建你的实体:
actor = Actor(image=resource_manager[key])
你会像这样创建它们:
actor = Actor(image_getter=SurfaceCapsule(resource_manager, key))
其中resource_manager
将是管理游戏所有表面的对象。
class RessourceManager(dict):
def __getitem__(self, key):
# implement lazy loading if you want, or load all images at startup
# load surface is necessary, cache it, and return it
def __load_surface_by_key(key):
# load stuff
在保存游戏状态之前,您必须clear()
,然后您可以快乐地将其序列化。
另一种方法是将actor的绘图外包,因此您只需将标识符存储到actor中的曲面上。
class Actor(object):
def __init__(self, **kwargs):
self.image_key = kwargs['image_key']
并在你的游戏课程中:
def draw(self):
for actor in self._actors:
self._screen.blit(resource_manager[actor.image_key], actor.pos)
但如果你的演员使用多个表面代表他们自己,这有点麻烦。