我的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
标志也可能更容易......或类似的东西。