使用 Pygame,在不同位置绘制图像的副本

Using Pygame, draw a copy of an image in a different location

这是对 this question:

的跟进

注意:这在 python 中,使用 pygame 库。

我想澄清一下这个声明,这是对上述问题的评论:

Another important thing, don't use the same Sprite() nor the same Rectangle in different locations. If you want to draw another copy of the same image in a new location make a copy of the rectangle, then create a new Sprite() object.

我有一组游戏资产,我想随机挑选一个来添加我的 精灵组。我目前是这样做的:

class TestSprite(pygame.sprite.Sprite):
    def __init__(self, strFolder):
        super(TestSprite, self).__init__()
        self.image = load_image(strFolder + 'x.png'))
        #....

def GetRandomAsset():
    rnd = random.randrange(1, 4)
    if rnd == 1:
        return TestSprite('assets/A/')
    elif rnd == 2:
        return TestSprite('assets/B/')
    elif rnd == 3:
        return TestSprite('assets/C/')
    else:
        return TestSprite('assets/D/')
    #....

my_group = pygame.sprite.Group()
my_group.add(GetRandomAsset())
#.....
#Control FPS
#Check Events
#Update State
#Clear Screen
#Draw Current State
#Update Display

一切正常;每次我 运行 上面的代码,一个新的精灵就会显示在屏幕上。我的问题是每次我添加一个精灵时,我都必须从磁盘加载它,即使我一遍又一遍地使用相同的 4 个图像。

我认为将我的所有资产存储在一个名为 PRELOADEDASSETS 的全局列表中会更聪明。然后每当我需要一个时:my_group.add(PRELOADEDASSETS[x]) 但是当我尝试这样做时,我只能拥有我的每项资产的一份副本。

如何预加载我的所有资产,然后在需要时获取存储的数据?

谢谢!

Another important thing, don't use the same Sprite() nor the same Rectangle in different locations. If you want to draw another copy of the same image in a new location make a copy of the rectangle, then create a new Sprite() object.

在这种情况下,这是一个有效的建议。将一个表面多次 blit 到不同的位置当然没有问题(例如使用不同的 Rects),但是如果你使用 Group 到 handle/simplify 你的绘图,你需要一个对象对于每个要绘制图像的位置。


回答您的实际问题:

您不需要缓存 Sprite 个实例。只需缓存 Surface 个实例。

这样,您可以使用不同的 Sprite 对象将相同的图像绘制到不同的位置。

一个简单的缓存实现可能如下所示:

images = {'a': load_image('assets/A/x.png'),
          'b': load_image('assets/B/x.png'),
          'c': load_image('assets/C/x.png'),
          'd': load_image('assets/D/x.png')}
...
class TestSprite(pygame.sprite.Sprite):
    def __init__(self, image_key):
        super(TestSprite, self).__init__()
        self.image = images[image_key]
...
def GetRandomAsset():
    image_key = random.choice(images.keys())
    return TestSprite(image_key)

这将预先加载所有图像(可能是也可能不是您想要的);添加惰性很容易,但您可能不希望出现延迟(最佳取决于实际加载的图像数量和加载时间)。

您甚至可以遍历游戏目录中的所有文件夹并自动检测并加载所有图像,但此类疯狂操作超出了本答案的范围。