1

为了轻松保存游戏的游戏状态,我倾向于序列化game包含所有游戏实体(又名演员)的对象。

我遇到的一个常见问题是你不能pickle pygamesurfaces,所以如果你的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模块腌制它。

如何解决这个问题?

4

1 回答 1

2

解决方案不是尝试序列化表面,而是从您的游戏/游戏实体中删除它们并使用延迟加载等技术,例如在恢复游戏状态后再次获取它们。

因此,与其将表面直接传递给实体,不如将其传递给负责存储/检索表面的对象:

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)

但是如果你的演员使用多个表面来代表他们自己,这有点麻烦。

于 2012-08-17T13:23:19.887 回答