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

时间:2015-02-01 02:56:14

标签: python list class pygame sprite

这是对this question

的跟进

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

我想对此声明做一些澄清,这是上述问题的评论:

  

另一件重要的事情,不要使用相同的Sprite()也不要相同   不同位置的矩形。如果你想绘制另一个副本   然后,新位置中的相同图像会生成矩形的副本   创建一个新的Sprite()对象。

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

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]) 但是当我尝试这样做时,我只能拥有每个资产的一份副本。

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

谢谢!

1 个答案:

答案 0 :(得分:2)

  

另一个重要的事情是,不要在不同的位置使用相同的Sprite()和相同的Rectangle。如果要在新位置绘制同一图像的另一个副本,请复制该矩形,然后创建一个新的Sprite()对象。

在此上下文中,这是一个有效的建议。将表面多次blit到不同位置(例如,使用不同的Rect)当然没有问题,但如果使用Group来处理/简化绘图,则需要每个要绘制图像的位置都有一个对象。


回答你的实际问题:

您不需要缓存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)

这将预先加载所有图像(可能或可能不是你想要的);添加懒惰很容易,但你可能不想要可能的滞后(最好的取决于你实际加载的图像数量和时间)。

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