的解决方案是,不要试图serialze表面,而是把它们从你的游戏/游戏实体删除和使用的技术像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()
它,然后你就可以happilly序列化。
另一种方法是将演员的绘图外包,因此您只需将标识符存储在演员的曲面中即可。
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)
但如果你的角色使用一个以上的面表示theirself这是有点麻烦。
我想有一个方法来“黑名单”的成员,所以泡菜跳过他们。你能做到这一点,咸菜元组或字符串表示的图像文件路径或ID,您使用加载它? – ninMonkey 2012-10-03 15:16:16
@monkey是的,[你能做到这一点(http://stackoverflow.com/questions/6313421/can-i-mark-variables-as-transient-so-they-wont-be-pickled)。如果你的游戏很小,这是一个明智的做法。但是,如果游戏变得越来越大,那么无论如何你都希望将资源加载功能转移到单独的类中。 – sloth 2012-10-03 19:35:05