Not:

Bu blog için açmış olduğum Twitter feed hesabımı takip ederek, yeni yazılarımdan daha rahat haberdar olabilirsin!

AABB* Algoritması ile Collision Dedection ve Response İşlemleri

Oyunlarda çarpışma algılamaları ve tepkileri için birçok algoritma kullanılır. Bunlardan en yaygın kullanılanlardan biri ise AABB algoritmasıdır. Dörtgen biçimli objelerde kullanırız. Mantığını biraz açıklamaya çalışalım.

Şimdi 2 adet kare biçiminde objemiz var. Algoritma bize der ki; bu 2 objenin x eksenindeki uzaklıkları bu iki objenin genişliklerinin yarısının toplamından, y eksenindeki uzaklıkları bu iki objenin yüksekliklerinin yarısının toplamından küçük ise bu iki obje çarpışıyor anlamına gelir. Bu koşulu biraz formülize etmeye çalışalım; 

```
|x2-x1| < w1/2+w2/2 Λ |y2-y1| < h1/2+h2/2
```


Peki çarpışmanın olup olmadığını bu şekilde anladık. Peki tepkiyi neye göre vereceğiz? x eksenindeki fazlalığı mı atacağız, y eksenindeki fazlalığı mı? Bu sorunun cevabı çok basit, hangi eksendeki fazlalık azsa o eksende tepki vereceğiz. Şimdi bunları GML ile kodlara dökelim (Siz kullandığınız dil yada ortamda deneyebilirsiniz);

```javascript
//Carpisma Algılaması için AABB Metodu Kullanılıyor
//AABB method is AABB metodunun formulü kısaca şudur
//|x2-x1| < w1/2+w2/2 && |y2-y1|<h1/2+h2/2 Bu koşul doğruysa çarpışma var demektir.

//2 Objenin X ve Y Mesafelerine İhtiyacımız Var
var distance_x=target_obj.x-x;
var distance_y=target_obj.y-y;
//Objelerin Genişlik ve Yükseklik Değerleri Alınıyor
var w=bbox_right-bbox_left;
var h=bbox_bottom-bbox_top;
var tw=target_obj.bbox_right-target_obj.bbox_left;
var th=target_obj.bbox_bottom-target_obj.bbox_top;

//True Distance Değerleri Çarpışma Olmaması İçin Iki Obje Arasında Olması Gereken Minimum Mesafedir
var true_distance_x=w/2+tw/2;
var true_distance_y=h/2+th/2;
//AABB Metoduna Göre Çarpışma Olup Olmadığı Kontrol Ediliyor
if(abs(distance_x)<true_distance_x && abs(distance_y-vv)<true_distance_y){
    var false_distance_x,false_distance_y;
//2 Obje Arasındaki Fazlalık Olan Mesafe Hesaplanıyor
   false_distance_x=true_distance_x-abs(distance_x);
   false_distance_y=true_distance_y-abs(distance_y);
//Çarpışmaya tepki veriyoruz. 
//Eğer X Eksenindeki Fazlalık, Y Ekseninden Azsa Çarpışma Tepkisini X Ekseninde Vermeliyiz 
    if(abs(false_distance_x)<abs(false_distance_y)){
        x+=hv-false_distance_x*sign(distance_x);
    }else{
        y+=vv-false_distance_y*sign(distance_y);
    }
}
```

Yorumlar