最近在學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:最近看一本書上講到通過繪制蒙版,進而通過顏色來檢測碰撞的,准備試驗一下.