pygame游戏有时会因这段代码而崩溃



我的pygame游戏 我正在比较 2 个对象之间的距离,并在它们靠得太近时尝试"弹出"它们,但有时(看似随机(代码在碰撞时崩溃。 如果有人能帮助我,那就太好了。

错误消息是:

IndexError: list index out of range

相关代码:

for i in reversed(range(len(birdies))):
birdies[i].moveBird()
birdies[i].calcSpeeds()
birdies[i].drawEnemyBird()
for j in reversed(range(len(shots))):
if distance(birdies[i].x, birdies[i].y, shots[j].x, shots[j].y) < shots[j].rad/2 + birdies[i].width/2:
birdies.pop(i)
shots.pop(j)

我会提出一个替代解决方案。

由于列表以相反的顺序迭代,因此唯一的问题是birdies.pop(i)内部循环,正如@Kingsley所指出的。

在外部循环中添加状态pop_bird,并在必须删除 birs 时在内部循环中设置状态:

for i in reversed(range(len(birdies))):
birdies[i].moveBird()
birdies[i].calcSpeeds()
birdies[i].drawEnemyBird()
pop_bird = False
for j in reversed(range(len(shots))):
if distance(birdies[i].x, birdies[i].y, shots[j].x, shots[j].y) < shots[j].rad/2 + birdies[i].width/2:
pop_bird = True
shots.pop(j)
if pop_bird:
birdies.pop(i)

如果一只鸟被击中,break内循环可能就足够了,因为一只鸟不能被射杀两次:

for i in reversed(range(len(birdies))):
birdies[i].moveBird()
birdies[i].calcSpeeds()
birdies[i].drawEnemyBird()
for j in reversed(range(len(shots))):
if distance(birdies[i].x, birdies[i].y, shots[j].x, shots[j].y) < shots[j].rad/2 + birdies[i].width/2:
birdies.pop(i)
shots.pop(j)
break

问题是代码正在迭代列表,有时会删除条目,但随后期望它们在下一次迭代中出现。

for j in reversed(range(len(shots))):
if <collision>:
birdies.pop(i)             # <-- HERE
shots.pop(j)   

假设删除了birdies元素。 小鸟的范围没有重新计算,所以在下一次循环shots时,它仍然试图检查它刚刚删除的元素。

你能用其他方式循环吗?

hit_birds = []
for b in birdies:
...
for s in shots:
if ( shotHits( b, s ) ):    # TODO: write this function
hit_birds.append( b )   # just record which birds are hit
# remove shot birds
birdies = [ b for b in birdies if b not in hit_birds ]

从长远来看,将所有bird 数据封装到一个列表或类中,并在迭代期间简单地设置bird.hit标志也可能更容易......或类似的东西。

最新更新