You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

敌方子弹撞墙触发ValueError: list.remove(x): x not in list错误求助

问题原因

敌方子弹会在单次update循环中被两次调用delete方法,导致第二次执行self.list.remove(self)时,子弹已经不在目标列表中,抛出ValueError: list.remove(x): x not in list:

  • 第一步:执行bullet.move()时,若子弹出界(y坐标超出±300),会调用delete()将子弹从bullets列表移除;
  • 第二步:后续的墙体碰撞检测中,该子弹对象仍存在(仅被隐藏),如果距离墙体小于15,会再次调用delete(),此时子弹已不在列表,触发报错。

玩家子弹未出现该问题,是因为其飞行轨迹很少同时满足「出界」和「碰撞敌人」的条件,不会触发重复删除。

解决方案

给Bullet类增加存活状态标记,避免重复执行删除逻辑,同时在所有触发删除的环节先检查状态:

修改Bullet类

class Bullet(Turtle):
    def __init__(self, player, list):
        super().__init__()
        self.speed(0)
        self.ht()
        self.pu()
        self.color("white")
        self.goto(player.xcor(), player.ycor())
        self.setheading(player.heading())
        self.forward(40)
        self.list = list
        self.st()
        self.alive = True  # 新增:标记子弹存活状态

    def move(self):
        if not self.alive:  # 已死亡的子弹跳过移动逻辑
            return
        self.forward(15)
        if self.ycor()>300 or self.ycor()< -300:
            self.delete()
            
    def delete(self):
        if not self.alive:  # 避免重复执行删除操作
            return
        self.ht()
        self.alive = False
        self.list.remove(self)

修改敌方子弹的碰撞检测逻辑

在检测墙体碰撞前,先判断子弹是否存活:

# check for collision with a wall
for wall in walls[:]:
    if bullet.alive and bullet.distance(wall)<15:
        wall.strike()
        bullet.delete()

可选优化:统一玩家子弹的处理逻辑

为了避免后续出现类似问题,玩家子弹的循环建议也使用切片复制列表,并增加存活状态检查:

# move bullets fired by the player
for bullet in player.rounds[:]:  # 用切片复制列表,避免列表修改干扰循环
    if not bullet.alive:
        continue
    bullet.move()
    # check for collision with an enemy
    for alien in enemies:
        if bullet.distance(alien)<20:
            bullet.delete()
            alien.delete(enemies)

这样就能彻底解决重复删除导致的报错,同时让子弹的状态管理更严谨。

内容的提问来源于stack exchange,提问作者Yin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 18:36:25