2012-08-17 35 views
1

輕鬆保存我的遊戲的遊戲狀態,我傾向於我的序列化對象game包含所有遊戲實體(又名演員)。我應該如何序列化包含pygame的表面遊戲中的對象?

一個共同的問題我遇到的是,你不能泡菜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

我想有一個方法來「黑名單」的成員,所以泡菜跳過他們。你能做到這一點,鹹菜元組或字符串表示的圖像文件路徑或ID,您使用加載它? – ninMonkey 2012-10-03 15:16:16

+0

@monkey是的,[你能做到這一點(http://stackoverflow.com/questions/6313421/can-i-mark-variables-as-transient-so-they-wont-be-pickled)。如果你的遊戲很小,這是一個明智的做法。但是,如果遊戲變得越來越大,那麼無論如何你都希望將資源加載功能轉移到單獨的類中。 – sloth 2012-10-03 19:35:05

回答

2

的解決方案是,不要試圖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這是有點麻煩。

相關問題