如何深度复制包含pygame.Surface的对象?

How to deepcopy object which contains pygame.Surface?

我正在 pygame 中编写一个 2D 游戏引擎,但我有点卡在编写 spawner class 中。 我想要实现的是一种创建生成器的简单方法,例如:

bullet = Bullet()
spawner = Spawner()
spawner.set_spawn_object(bullet)

我在 set_spawn_object

中使用 copy.deepcopy

基本上我想将一个对象传递给 spawner,它应该深度复制该对象并保留该副本。然后每隔 n 秒,它将通过将对象复制到呈现碰撞等的游戏对象的全局列表来生成该对象。我需要一个深度复制,因为我想稍后单独修改它们(例如位置、名称、纹理)。问题是无法以这种方式复制曲面。

现在我的游戏引擎中的每个对象都有自己的表面,我打算做的是将所有表面分开 class 以提高效率。那可以解决那个问题,因为我不会复制表面。但是...

假设我有一个 bullet 和一个 resource_manager 对象。 bullet 有一个指向 resource_manager.bullet_texture 的指针(它是 pygame.Surface)。

那我可以 bullet2=copy.deepcopy(bullet) 因为我会复制指针,而不是表面本身。

问题是python没有指针,那我该怎么办?

您不能在 pygame.Surface 上使用 copy 模块,但是 Surface 有自己的 Surface.copy 方法。

您可以为您的 类 定义一个 copy 方法,它使用 Surface 实例的 Surface.copy 方法创建一个包含所有所需属性副本的新实例。

如果你有很多属性,你可以使用特殊的内置属性__dict__:它包含一个属性(键)及其值的字典,你可以遍历它来分配给每个属性为原件的副本。

一个非常简单的例子:

class Myobject:
    def __init__(self, image=None, rect=None):
        self.image = image #a pygame surface
        self.rect = rect #a rectangle
        self.level = 0

    def copy(self):
        copyobj = Myobject()
        for name, attr in self.__dict__.items():
            if hasattr(attr, 'copy') and callable(getattr(attr, 'copy')):
                copyobj.__dict__[name] = attr.copy()
            else:
                copyobj.__dict__[name] = copy.deepcopy(attr)
        return copyobj

现在如果你这样做:

myobj = Myobject(an_image, a_rectange)
myobj2 = myobj.copy()

myobj2myobj 的 "copy"。它的图像和矩形是具有相同值的不同实例,您可以安全地编辑后者而前者保持不变。

所以,如果你想创建一个生成器,生成器可能会调用传递对象的 copy 方法。

class Spawner:
    @staticmethod
    def set_spawn_object(obj):
        return obj.copy()