IndexError:列表超出范围

时间:2013-03-18 23:05:30

标签: python pygame

我正在制作一个类似于Intellivision的旧Astrosmash游戏的程序。无论如何,我一直试图获得一个爆炸的动画,我一直收到这个错误。我会盲目地看着这个,并想知道是否还有其他人能看到发生了什么。这是代码(它仅用于爆炸的精灵):

import pygame

class Explosion(pygame.sprite.Sprite):
    def __init__(self,color,x,y):
        pygame.sprite.Sprite.__init__(self)
        self.frame = 0
        self.width = 0
        self.height = 0
        self.x_change = 0
        self.y_change = 0
        self.images = []
        for i in range (0,25):
            img = pygame.image.load('Explosion'+str(i)+'.png').convert()
            img.set_colorkey([0,0,0])
            self.images.append(img)
        self.image = self.images[0]
        self.image_iter = iter(self.images)
        self.rect = self.image.get_rect()
        self.rect.left = x
        self.rect.top = y

    def update(self):
##        print("Update to frame ",self.frame)
##        self.frame += 1
##        self.image = self.images[self.frame]
        self.image = next(self.image_iter)

这是错误:

追踪(最近一次通话):   文件“C:\ Users \ Steve \ Desktop \ Project April \ Alien Metor Storm v1_4 \ AlienMetorStorm.py”,第560行,     主要()   文件“C:\ Users \ Steve \ Desktop \ Project April \ Alien Metor Storm v1_4 \ AlienMetorStorm.py”,第222行,主要     ships.update()   更新中的文件“C:\ Python31 \ lib \ site-packages \ pygame \ sprite.py”,第399行     对于self.sprites()中的s:s.update(* args)   文件“C:\ Users \ Steve \ Desktop \ Project April \ Alien Metor Storm v1_4 \ explosion.py”,第26行,更新     self.image = next(self.image_iter) StopIteration异常

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

  

动画长25帧......

仔细检查一下。你有代码:

for i in range (1,25): 
  # ... create an img

这是24帧长。

答案 1 :(得分:1)

我不确定问题究竟在哪里,因为一旦有人指出明显的第一个问题就改变了代码,并且之后再次更改了代码,并且现在还不清楚你在哪里弄错了。

此外,代码中你很有可能没有出现 - 如果你多次拨打update,你就会遇到这个问题。但是你没有告诉我们你在哪里打update。从追溯中,我可以看到for s in self.sprites(): s.update(*args),因此问题很可能只是sprites是一个比images更大的数组。但这只是猜测。

但我注意到print("Update to frame ",self.frame)在<{em> self.frame之前打印+= 1 的值,这可能会在您的调试中误导您。你看到它打印Update to frame 24,然后你得到IndexError试图阅读第25帧......

无论如何,正是这种“fencepost”或“off-by-one”错误就是为什么Python为你提供了很多方法来避免直接使用索引。构建一个包含理解的列表,使用for image in images:迭代一个列表,迭代一个带有for index, image in enumerate(images):索引的列表等。

那么,当迭代是隐式的时,你会做什么,分散到可能来自任何地方的update的一堆调用?

使用迭代器。

改变这个:

self.frame = -1
# ...
print("Update to frame ",self.frame)
self.frame += 1
self.image = self.images[self.frame]

......对此:

self.image_iter = iter(self.images)
# ...
self.image = next(self.image_iter)

或者,如果您想获取帧编号(例如,用于打印):

self.image_iter = enumerate(iter(self.images))
# ...
frame, self.image = next(self.image_iter)
print("Update to frame ", frame)

现在,你无法获得IndexError