最近在学Pygame,花一段时间做了一个异常简陋版的"打砖块".
这次重点说一下困扰我比较长时间的碰撞检测(个人太菜..).
按照网上教程比较普遍的方法(也可能是我没看见别的),碰撞检测依次计算移动物体与被碰撞物体各个边之间坐标是否相交.例如下列代码,检测小球与窗口的碰撞:
def baffleJudge(self):'''与墙壁之间的碰撞判断'''if self.vector.x > WINDOW_X - self.image.get_width():self.vector.x = WINDOW_X - self.image.get_width()elif self.vector.x < 0:self.vector.x = 0
计算小球的x值是否大于(小于)两侧边际的坐标.
可是,因为这种方法由于需要加减各种数值,很容易多加一个少减一个,出现乱七八糟的错误.所以我想了一种相对简便些的方法(后来看空间解析的书知道是变量的加减).
原理很简单:
检测A,B两个矩形(图片均为矩形)是否碰撞,只要检测两个矩形x轴集合之间,y轴的集合之间是否相交即可,也就是:(Xa1:Xa2) 与(Xb1:Xb2)之间, (Ya1:Ya2)与(Yb1:Yb2)之间是否相交.
代码如下:
1 def xy(self): 2 ''' 3 x1:上,x2:下 4 y1:左,y2:右 5 :return: 6 ''' 7 x1 = int(self.vector.x) 8 x2 = int(x1 + self.width) 9 y1 = int(self.vector.y) 10 y2 = int(y1 + self.height) 11 return(range(x1,x2+1),range(y1,y2+1)) 12 13 def cross(self, a, b): 14 ''' 15 判断两个集合是否相交 16 :return:相交返回True 17 ''' 18 for each in a: 19 if each in b: 20 return True 21 return False 22 23 def impactJudge(self, objects): 24 ''' 25 碰撞测试 26 :param objects: 27 :return: 28 True:碰撞成立 29 ''' 30 self.listX,self.listY = self.xy() 31 32 if(self.cross(self.listX, objects.listX) and #两物体x轴集合相交 33 self.cross(self.listY, objects.listY)): #两物体y轴集合相交 34 return True 35 else: 36 return False
impactJudge()小球类的方法,object则为与小球相撞的物体.若检测两组集合均相交则证明两图形碰撞成立. 大概就是这样,如果有错误请不吝赐教
PS:最近看一本书上讲到通过绘制蒙版,进而通过颜色来检测碰撞的,准备试验一下.