1

ゲームのゲーム ステートを簡単に保存するために、gameすべてのゲーム エンティティ (別名アクター) を含むオブジェクトをシリアル化する傾向があります。

私がよく遭遇する問題は、 pygame surfaceをピクルできないことです。そのため、アクター クラスが次のようになっているとします。

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モジュールでピクルすることはできません。

これを回避する方法は?

4

1 に答える 1

2

解決策は、サーフェスをシリアル化しようとするのではなく、ゲーム/ゲーム エンティティからそれらを削除し、ゲームの状態を復元した後に、遅延読み込みなどの手法を使用して再取得することです。

そのため、サーフェスを直接エンティティに渡す代わりに、サーフェスの保存/取得を担当するオブジェクトを渡します。

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()ます。そうすれば、喜んでシリアル化できます。


もう 1 つの方法は、アクタの描画を外注することです。その場合は、アクタのサーフェスに識別子を保存するだけです。

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)

しかし、アクターが自分自身を表現するために複数のサーフェスを使用する場合、これはやや面倒です。

于 2012-08-17T13:23:19.887 に答える