Cuma, Kasım 27, 2009

Oyunlarda Basit AI(Yapay Zeka) Uygulamaları

İnternette oyun programlama ile ilgili araştırma yaparken bulduğum basit ama faydalı iki AI algoritmasından bahsedeceğim. Bunlar Dikdörtgen Çarpışma(rectangle collision)ve Dolaşan(Roaming) AI türlerinden Kovalama algoritmaları. Eğer ki -ben kod inceleyerek daha iyi anlarım diyorsanız yazının sonuda bu algoritmaları kullanarak Allegroda hazırladığım ufak bir uygulamayı bulabilirsiniz.

1-Dikdörtgen Çarpışma(Rectangle Collision) Algoritması

Olay son derece basit. İki boyutlu düşünecek olursak çarpışma ne demektir. İki farklı nesnenin sağından - solundan veya altından-üstünden acıcıkta olsa iç içe geçmeleri değil midir. Bu mantıktan yola çıkarak nesnelerin etrafında dikdörtgenden bir çerçeve varmış gibi düşünüp ayrı ayrı koordinat eksenindeki 4 noktasını öğrenip bunları bir birleri ile karşılaştırdığımızda sonuca gitmiş oluruz. Aşağıdaki kod uygulamadaki dikdörtgen çarpışma algoritmatsına ait olan kısım.

bool carpismaKontrol(Kahraman *pKahraman, Dusman *pDusman)
{
int dusmanLeft,dusmanRight,dusmanTop,dusmanBottom;
int kahramanLeft,kahramanRight,kahramanTop,kahramanBottom;
bool durum=true;

dusmanLeft = pDusman->getLeft(); // (x)
dusmanRight = pDusman->getRight(); // (x + resim->w)
dusmanTop = pDusman->getTop(); // (y)
dusmanBottom = pDusman->getBottom(); // (y + resim->h)

kahramanLeft = pKahraman->getLeft(); // (x)
kahramanRight = pKahraman->getRight(); // (x + resim->w)
kahramanTop = pKahraman->getTop(); // (y)
kahramanBottom = pKahraman->getBottom(); // (y + resim->h)

if (kahramanLeft>dusmanRight)
durum = false;
else if (kahramanRight<dusmanLeft)
durum = false;
else if (kahramanTop>dusmanBottom)
durum = false;
else if (kahramanBottom<dusmanTop)
durum = false;

return durum;
}




2- Kovalama Algoritması

Oyundaki bir nesnenin başka bir nesneyi takip etmesidir. Buradaki mantık ise kovalayanın X ve Y değerlerinin kovalananın X ve Y sine göre azaltılması veya arttırlmasına dayanır. Aşağıdaki kod benim hazırladığım uygulamadaki kovalama AI sine ait olan kısımdır.

void
Dusman::yakala(Kahraman *pKahraman)
{
int dusmanX = getX();
int dusmanY = getY();

sayac++;
if (sayac % hiz ==0)
{
if (rand() % zekaPuani == 0)
{
if (pKahraman->getX()>dusmanX)
dusmanX++;
else if (pKahraman->getX()<dusmanX)
dusmanX--;

if (pKahraman->getY()>dusmanY)
dusmanY++;
else if (pKahraman->getY()<dusmanY)
dusmanY--;

sayac = 0;
}
}
setXY(dusmanX,dusmanY);
}



Yukarıdaki kodda ilk iki if bloğu (if (sayac % hiz ==0) ve if (rand() % zekaPuani == 0)) olaya biraz rasgelelik katmak içindir. Bir nevi kovalayanın zeka seviyesi veya hızı olarak düşünülebilir.

Ekran Görüntüsü


Öncelikle çizimler için kusura bakmayın aceleye geldi yoksa o kadarda beceriksiz sayılmam :P. Uygulama Code::Blocks IDE si kullanılarak MinGW ile derlenmiştir buradan indirebilirsiniz.

Bir sonraki yazıda netten hazır olarak bulduğum spriteları kullanarak karakterimizin resmini doğrultusuna göre değişecek ve çarpışma anında müzik çalacak hale getirmeyi düşünüyorum.

Hiç yorum yok: