的解決方案是,不要試圖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