2012-08-17 5 views
1

내 게임의 게임 상태를 쉽게 저장하기 위해 모든 게임 엔터티 (a.k.a. actors)가 포함 된 game 개체를 일련 화하는 경향이 있습니다.파이 게임 표면이있는 게임 개체는 어떻게 직렬화해야합니까?

I 발생할 일반적인 문제는 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

+0

@monkey 예, [할 수 있습니다] (http://stackoverflow.com/questions/6313421/can-i-mark-variables-as-transient-so-they-wont-be-pickled). 게임이 아주 작 으면 합리적인 방법입니다. 그러나 게임이 점점 더 커지면 어쨌든 리소스를로드하는 기능을 별도의 클래스로 옮기고 싶습니다. – sloth

답변

2

해결 방법은 표면을 연재시키려는 것이 아니라 게임/게임 엔터티에서 표면을 제거하고 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'] 

및 게임 클래스

: 당신의 배우 theirself을 표현하기 위해 하나 이상의 표면을 사용하는 경우

def draw(self): 
    for actor in self._actors: 
     self._screen.blit(resource_manager[actor.image_key], actor.pos) 

하지만이 다소 복잡합니다.