我是PyGame和python的新用户。话虽这么说,我已经创建了一些精灵并将它们组成一组。例如,
gems = pygame.sprite.Group()
for i in range (0,4):
gem = Gem()
all_sprite_list.add(gem)
gems.add(gem)
现在在我的主要内容中,我想通过点击特定键来操纵组中的一个gem。我目前正在通过为每个gem设置一个id属性并遍历该组来完成此操作,直到我将id与我想要操作的id匹配。即:
if event.type == pygame.KEYDOWN and event.key == pygame.K_F1:
for gem in gems:
if gem.id == 1:
gem.state = normal
elif event.type == pygame.KEYDOWN and event.key == pygame.K_F2:
for gem in gems:
if gem.id == 2:
gem.state = normal
我知道这是一个肮脏的肮脏伎俩,我确信有一种更好的方法,而不是通过群体迭代。我看了一下参考文献,并尝试做类似
的事情gems.sprites().index(0)
无济于事。有什么建议?
答案 0 :(得分:0)
您似乎知道哪些键与哪个ID相对应,因此您可以将该信息放入dict中,然后只通过gems进行一次迭代:
gem_keys = {
1: pygame.K_F1,
2: pygame.K_F2,
}
if event.type == pygame.KEYDOWN:
for gem in gems:
# Check if key pressed corresponds to current gem
if event.key == gem_keys[gem.id]:
gem.state = normal
除了代码感觉笨拙之外,您是否有任何具体问题?
答案 1 :(得分:0)
在PyGame的Sprite
课程中,你有一个函数update(*args)
(documentation)。
(另外,*args
表示您可以根据需要传入任意数量的参数:
>>> def f(*args):
... print args
...
>>> f(1,2)
(1, 2)
>>> f(3)
(3,)
>>> f(3,5,6)
(3, 5, 6)
>>> def g(*args):
... print args[0]
...
>>> g(1,2)
1
默认情况下update
不执行任何操作,但您可以为自己的目的覆盖它,例如通过创建一个覆盖基类Sprite
类的类:
class MySprite(Sprite):
def update(self,*args):
key = args[0]
if key == pygame.K_F1 and self.id == 1 :
self.state = normal
elif key == pygame.K_F2 and self.id == 2 :
self.state = normal
现在,Sprite Groups还有一个update
函数(具有相同的签名update(*args)
)
这个函数的作用是使用每个sprite上传入的参数调用update
# group has sprite1 and sprite2
group.update(1,2,3) # same as calling sprite1.update(1,2,3)
# and sprite2.update(1,2,3)
所以,如果gems
是您的群组,则可以执行此操作(假设您使用的是上述MySprite
类)
if event.type == pygame.KEYDOWN:
gems.update(event.key)
# this will call the MySprite.update function for all the gems
答案 2 :(得分:0)
我写了another answer,似乎是用于更新PyGame精灵的规范答案(特别是如果你每次更新都更新了很多精灵)。但是这里有一个替代解决方案,用于更新许多精灵的情况。
目标是在大型集合中查找一小组对象。在这里,我提出的解决方案是与您的精灵组一起使用并行字典。该词典将键入触发它的键。
在这里,我们将使用defaultdict
(请查看此question(尤其是第二个答案)以了解如何使用这些内容)。基本上它是一个带有默认值的字典(这里因为list
填充了空列表)。
key_dict = defaultdict(list)
# add the sprite triggered by F1
key_dict[pygame.K_F1].append(gem1)
# you can add multiple sprites as well (these are lists)
key_dict[pygame.K_F2].append(gem2)
key_dict[pygame.K_F2].append(gem3)
#... in your update loop
if event.type == pygame.KEYDOWN:
for gem in key_dict[event.key] : #this gets all the gems for this key event
# (empty if not defined because defaultdict)
gem.state = normal
如果你有一个很多的宝石,并且只需要碰几个小宝石,这个解决方案就不错了。
但是存在一些问题:
你需要保留两个集合(你的精灵组和这个)
如果你将它用于很多宝石,那么速度优势会更低
这将使您的代码更加混乱
我认为只有在你要更新的宝石数远远少于宝石总数的情况下才值得这样做。如果你正在更新很多其他的属性,我会建议我的另一个答案,作为它的清洁。