2012-08-17 58 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这是有点麻烦。

相关问题