迭代列表(索引超出范围)

时间:2016-09-01 02:29:52

标签: python python-3.x pygame

我正在创建的内容的快速摘要:这是一个游戏,其中外星飞船在屏幕周围反弹(如戴尔徽标/加载屏幕),具有一定的边界,使其保持在屏幕顶部附近。在屏幕的底部附近有一个玩家船只必须点击射击敌人太空入侵者的风格,同时左右移动(但此刻我仍在使用键盘/鼠标同时工作,因为事件只做顶部的队列)。还有母牛从母体下面传来奶牛。如果你抓到了牛,你会得到积分。如果你没有躲过一个,你会失去分数和生命。如果你用一个“网”捕获一个,你就会获得积分。

我遇到的问题是这个错误(cowRect = (cow_x[i], cow_y[i], 127, 76) IndexError: list index out of range),我认为这可能是因为程序在它们仍然为空时尝试迭代列表而引起的,尽管它看起来像列表中的项目正在“扫描”它。

我的代码的一些片段(它就像170行所以我不会发布所有代码):

开端 -

cowList = []
statusList = []
cow_x = []
cow_y = []

在主循环内部 -

if hits >= hitsNeeded and time.time() >= currentTime + 1:
        cowList.append(cownumber)
        cownumber += 1
        statusList.append(3)
        cow_x.append(random.randint(0, 573))
        cow_y.append(700)

也在主循环内 -

for i in statusList:
        cowRect = (cow_x[i], cow_y[i], 127, 76)
        if cow_y[i] + 111 < 0:
            statusList[i] = 0  #offscreen
        if cowRect.colliderect(missileRect):
            statusList[i] = 1  #exploded
            points -= 15
        netRect = (net_x, net_y, 127, 127)
        if cowRect.colliderect(netRect):
            points += 90
            screen.blit(milkplus, (cow_x[i], cow_y[i]))
            powerup = pygame.mixer.Sound("C:/Python35/powerup.mp3")
            powerup.play()
            shotNet = 0
            statusList[i] = 2  #caught
        if cowRect.colliderect(playerRect):
            points -= 10
            lives -= 1
            statusList[i] = 4  #player collision

    for i in statusList:
        if statusList[i] == 3:  #alive
            screen.blit(cow, (cow_x[i], cow_y[i]))
            cow_y[i] -= cowSpeed

是的,我确实意识到我并不需要有4种状态的牛,它只是有助于保持我的头脑组织(这也适用于其他一些事情)。

如果我犯了一些错误,我很抱歉,我很长时间没有来过这里。

1 个答案:

答案 0 :(得分:2)

您看到的问题是由于for循环在Python中的工作方式。它们遍历列表的内容,而不是列表索引。正如评论中所提到的那样,可以通过简单地执行for i in range(len(statusList))来修复错误,但我想建议您使用稍微不同的策略来编码有关奶牛的信息,方法是奶牛清单,而不是奶牛的四个清单。

class Cow:
    def __init__(x, y):
        self.status = 'alive'
        self.x = x
        self.y = y

开端 -

cows = []

在主循环内部 -

if hits >= hitsNeeded and time.time() >= currentTime + 1:
    cows.append(Cow(random.randint(0, 573), 700))

也在主循环内 -

for cow in cows:
    cowRect = (cow.x, cow.y, 127, 76)
    if cow.y + 111 < 0:
        cow.status = 'offscreen'
    if cowRect.colliderect(missileRect):
        cow.status = 'exploded'
        points -= 15
    netRect = (net_x, net_y, 127, 127)
    if cowRect.colliderect(netRect):
        points += 90
        screen.blit(milkplus, (cow.x, cow.y))
        powerup = pygame.mixer.Sound("C:/Python35/powerup.mp3")
        powerup.play()
        shotNet = 0
        cow.status = 'caught'  #caught
    if cowRect.colliderect(playerRect):
        points -= 10
        lives -= 1
        cow.status = 'collision'

for cow in cows:
    if cow.status == 'alive':
        screen.blit(cow_pic, (cow.x, cow.y))
        cow.y -= cowSpeed

这将使未来更容易。如果您对课程感到不舒服,可以使用collections.namedtuple获得类似的行为。