为了轻松保存游戏的游戏状态,我倾向于对包含所有游戏实体(也称为演员)的game
对象进行序列化。
我遇到的一个常见问题是您不能腌制pygame surfaces,因此,如果您的actor类如下所示:
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模块对其进行腌制。
如何解决这个问题?
最佳答案
解决方案不是尝试序列化表面,而是将其从您的一个或多个游戏实体中移除并使用类似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()
,然后才能对其进行序列化。另一种方法是将角色的图形外包,因此您只需将标识符存储到角色中的曲面即可。
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)
但是,如果您的演员使用多个表面来代表自己,这会有些麻烦。