Processing 3.5.4调用Enemy.collide报TypeError的碰撞检测问题求解
报错修复方案
直接报错原因
你触发报错的代码Enemy.collide(Bullets)存在两个核心问题:
collide是Enemy类的实例方法,必须通过你预先创建的enemy实例调用,不能直接用类名Enemy调用- 传入的参数
Bullets是类对象,不是具体的子弹实例,需要传入子弹列表中的单个子弹对象
核心代码修改
1. 修正draw函数中的碰撞检测逻辑
将原来的碰撞遍历代码替换为:
for b in bullet: enemy.collide(b)
2. 修正Enemy类的collide方法
你当前的collide方法中仍然用类名Bullets访问属性,需要替换为传入的子弹实例参数other,同时删除冗余的方法调用直接访问实例属性:
def collide(self, other): if (self.x + self.siz / 2 >= other.x - other.siz / 2 and self.x - self.siz / 2 <= other.x + other.siz / 2 and self.y + self.siz / 2 >= other.y - other.siz / 2 and self.y - self.siz / 2 <= other.y + other.siz / 2): print("YES") # 可选扩展:命中后移除子弹、扣除敌人生命值 if other in bullet: bullet.remove(other) self.health -= 10
3. 修复Bullets类的冗余代码
你定义的sx()、siza()方法没有加self参数,调用会报错,直接删除这两个方法,通过实例属性直接访问对应值即可。同时修正子弹渲染逻辑的坐标偏移问题:
# Bullets类的render方法修正 def render(self): pushMatrix() translate(self.x,self.y) stroke(113,195,0) beginShape() # 已经translate到当前子弹坐标,直接用相对坐标绘制即可 circle(0,10,5) endShape(CLOSE) popMatrix()
更优碰撞检测实现建议
- 采用圆形碰撞检测更适配当前的物体形状:你的子弹是圆形、敌人是三角形,外接圆碰撞计算效率更高,逻辑更简单:
import math def collide_circle(self, other): dx = self.x - other.x dy = self.y - other.y # 计算两个物体中心点的距离 dist = math.hypot(dx, dy) # 距离小于两个物体半径之和即判定为碰撞 if dist < (self.siz/2 + other.siz/2): print("YES")
- 遍历碰撞前先过滤出屏幕范围内的子弹,减少无效计算,提升运行性能
- 命中后先将待删除的子弹/敌人加入临时删除列表,遍历结束后统一删除,避免遍历过程中修改原列表导致的漏判问题
内容的提问来源于stack exchange,提问作者Gabriel Prosise
相关产品推荐
相关产品推荐

