…bir ajanı hedefe yumuşakça götürebilecek, kaçan bir hedefin önünü kesebilecek, sürü hâlinde hareket eden kuşlar/balıklar yapabilecek, birden çok davranışı çakışmadan birleştirebilecek ve motorunuzun yerleşik kaçınma sistemini bilinçli kullanabileceksiniz.
🤔 ISINMA: PAC-MAN HAYALETİ VS UZAY GEMİSİ
Pac-Man’in hayaleti bir kavşakta anında 90° döner. Bir uzay gemisi, bir araba ya da bir kuş bunu yapabilir mi?
Gerçek şeylerin kütlesi ve hızı var: dönmek zaman alır, frenlemek mesafe ister. Izgarada “bir kare sağa” hareketi bunu taşımaz.
Y0’da moveToward yazdık: hedefe sabit hızla düz gitmek. Yeterince “canlı” değil: köşeli, robotik.
Craig Reynolds’ın fikri: karakteri doğrudan konumlandırma, ona bir kuvvet uygula; hız ve konum fizikle değişsin. Sonuç: kavisli, ataletli, inandırıcı hareket.
🎯 Bu konu için bilmeniz gerekenler
Yeşil = gerekli · kesikli = faydalı ama şart değil. Tıklayınca ilgili sunuma gider.
Neden?Bu konu tamamen vektör üzerine kurulu: toplama, çıkarma, uzunluk, normalize, “uzunluğu en fazla şu olsun”. Y0’daki vektör oyun alanı ve dt bilgisi yeter. Sürüde “yakındaki kuşları bulmak” veri yapısı problemidir; geometrik arama ve hash sunumlarına bağlanacağız.
🧰 Kodlamadan korkuyorsanızUnity’de NavMeshAgent, Unreal’da CharacterMovement + RVO, Godot’da NavigationAgent zaten seek/arrive ve çarpışmadan kaçınma yapıyor. Bu sunum, onların içinde ne olduğunu ve ne zaman kendi davranışınızı yazmanız gerektiğini anlatıyor. Demoların hepsi kaydırıcıyla ayarlanabilir: önce oynayın.
Mini sözlük
steering · steering force
yönlendirme · direksiyon kuvveti
Ajanın hızını değiştirmek için uyguladığı kuvvet
desired velocity
istenen hız
Davranışın “şu yönde şu hızla gitmek istiyorum” vektörü
max speed · max force
azami hız · azami kuvvet
Ajanın fiziksel sınırları: ne kadar hızlı gidebilir, ne kadar keskin dönebilir
seek · flee · arrive
ara · kaç · yavaşlayarak var
Bir noktaya git / uzaklaş / yaklaşınca yavaşla
pursue · evade
takip (önünü kes) · kaçın
Hareketli hedefin gelecekteki konumuna göre ara / kaç
wander
dolaşma
Yumuşak, rastgele görünen dolaşma
separation · alignment · cohesion
ayrılma · hizalanma · bütünleşme
Boids’in üç kuralı
emergence
ortaya çıkan davranış
Basit yerel kurallardan karmaşık grup davranışı doğması
context map
bağlam haritası
Her yön için “ilgi” ve “tehlike” puanları tutan dizi
RVO / ORCA · flow field
karşılıklı kaçınma · akış alanı
Kalabalıkta çarpışmasız yürüme · her hücrede “buradan şuraya git” oku
LEVEL 0
Hareket katmanları
kovboy, at ve sığırlar
hareket katmanları
seek ve flee
arrive, pursue, wander
engeller ve yollar
boids ve sürüler
birleştirmek: context steering
kod ve laboratuvarlar
oyunlarda ve kütüphanelerde
Reynolds’ın üç katmanı (GDC 1999)
Reynolds’ın benzetmesi: sığır sürüsünden bir inek kaçar. Patron bir kovboya “onu getir” der (eylem seçimi). Kovboy atını ineğe doğru yönlendirir, engellerin etrafından dolaştırır (steering). At bacaklarını nasıl oynatacağını bilir (locomotion).
Önceki haftalar en üst katmandı. Y8–Y9’da (A*, NavMesh) rota bulacağız; steering o rotayı yumuşakça izler ve anlık engellerden kaçar.
Katmanların ayrı olması büyük kolaylık: aynı “kovala” kararı, bir kuş, bir araba ya da bir zombi için farklı locomotion ile çalışır.
🎒 Ön bilgi: konum, hız, ivme
Konum p: nerede? Hız v: saniyede ne kadar ve hangi yöne? İvme a: hız saniyede ne kadar değişiyor?
Newton: kuvvet = kütle × ivme. Kütleyi 1 alırsak kuvvet = ivme.
Her karede (Y0’daki dt ile) Euler adımı: önce hızı, sonra konumu güncelle.
İki sınır karakteri “kişiliklendirir”: azami hız (ne kadar hızlı) ve azami kuvvet (ne kadar çevik). Hızlı ama hantal bir tank, yavaş ama çevik bir kedi.
Reynolds’ın formülü: direksiyon = istenen − mevcut
Davranış söyler: “şu yönde, şu hızla gitmek istiyorum” (istenen hız).
Ajan şu an başka bir hızla gidiyor. Aradaki fark, uygulanması gereken düzeltme kuvveti.
Kuvvet azami kuvvetle kırpılır: ajan bir anda dönemez, yavaş yavaş döner. Kavisli hareket buradan gelir.
Bütün steering davranışları bu kalıbı kullanır; değişen tek şey istenen hızın nasıl hesaplandığı.
Quiz 1 · katmanlar
Bir ajan sağa doğru tam hızla giderken hedef tam arkasında kalırsa “seek” direksiyon kuvveti hangi yönü gösterir?
İstenen hız hedefe (sola) doğru azami hız; mevcut hız sağa. Fark = istenen − mevcut, sola doğru iki kat büyüklükte bir vektördür (azami kuvvetle kırpılır). Ajan önce yavaşlar, sonra sola hızlanır: frenleyip geri dönen bir araç gibi.
LEVEL 1
Seek ve flee
en basit iki davranış
hareket katmanları
seek ve flee
arrive, pursue, wander
engeller ve yollar
boids ve sürüler
birleştirmek: context steering
kod ve laboratuvarlar
oyunlarda ve kütüphanelerde
Elle seek: kare kare, sayılarla 🎯
Formülün tamamı üç satır: istenen hız = hedefe doğru, azami hızla (yeşil). Direksiyon = istenen − şimdiki hız (kırmızı), ama boyu azami kuvveti geçemez. Sonra hız += direksiyon, konum += hız. “İleri ▶|” ile kare kare ilerleyin ve mavi okun (şimdiki hız) yeşile nasıl yaklaştığını izleyin.
Seek ve flee
Seek’in kusuruHedefe tam hızla gider ve üstünden geçer; sonra geri döner, yine geçer… Hedefin etrafında yörüngeye girer. Bir hayalet için iyi, bir arabanın park etmesi için kötü. Çözüm: arrive (sonraki bölüm).
Flee’nin kusuruSonsuza kadar kaçar. Genelde bir “panik yarıçapı” eklenir: tehdit yakınsa kaç, uzaksa normal davranışa dön (demoda kırmızı kesikli çember).
Canlı: vektörleri görün 🎯
Fareyi ajanın arkasına götürün: kırmızı direksiyon oku geriye dönüyor, ajan kavis çizerek dönüyor.
Azami kuvveti 40’a indirin: ajan bir gemi gibi geniş dönüyor. 800’e çıkarın: bir sinek gibi keskin.
Fareyi bir noktada sabit tutun: ajan hedefin etrafında yörüngeye giriyor mu? (Seek’in kusuru.)
“Flee (kaç)” seçin: kırmızı çember panik yarıçapı. Ajanı bir köşeye sıkıştırabiliyor musunuz?
▶| 1 kare ile adım adım ilerleyin: her karede yeşil (istenen) ile mavi (mevcut) arasındaki fark = kırmızı.
Hedefin etrafına bir yavaşlama yarıçapı çiz. Dışarıdaysa seek gibi tam hız.
İçerideyse istenen hız mesafeyle orantılı küçülür: hız = azami × (mesafe / yarıçap). Hedefte hız sıfır.
Park eden araba, köşeye gelen asker, yanınıza koşup duran köpek…
Pursue: önünü kesmekHareketli bir hedefi seek ile kovalarsanız hep arkasından gidersiniz. Pursue, hedefin T saniye sonraki konumunu tahmin eder ve oraya gider. Basit T: mesafe / benim azami hızım (yakınsa az, uzaksa çok ileri bak). Evade aynı tahmine göre kaçar.
Wander: yumuşak rastgelelikHer karede tamamen rastgele yön = titreyen, sinirli bir ajan. Reynolds’ın hilesi: ajanın önüne bir çember koy, çemberin üstünde bir hedef noktası tut ve o noktayı her karede biraz kaydır. Yön değişimleri yumuşak ve doğal olur.
Canlı: arrive, pursue, evade, wander
Arrive: fareyi sabitleyin; ajan sarı çemberin içinde yavaşlayıp tam üstünde duruyor. Seek ile karşılaştırın.
Pursue: mor bot sekerek dolaşıyor. Ajan botun önüne (tahmini konuma) koşuyor mu? Mor kesikli çizgi tahmin.
Evade: ajan botun gelecekteki konumundan kaçıyor; bot ona doğru gelirken erkenden kenara çekiliyor.
Wander: turuncu çember ve üstündeki nokta. Ajan sarhoş gibi değil, keşif yapan bir hayvan gibi gezmeli.
Hepsinde azami kuvveti düşürün: tahmin doğru olsa bile hantal bir ajan yakalayamıyor. Zorluk ayarı için güzel bir düğme!
🔎 DEMODA DENEYİN
Arrive: fareyi sabitleyin; ajan sarı çemberin içinde yavaşlayıp tam üstünde duruyor. Seek ile karşılaştırın.
Pursue: mor bot sekerek dolaşıyor. Ajan botun önüne (tahmini konuma) koşuyor mu? Mor kesikli çizgi tahmin.
Evade: ajan botun gelecekteki konumundan kaçıyor; bot ona doğru gelirken erkenden kenara çekiliyor.
Wander: turuncu çember ve üstündeki nokta. Ajan sarhoş gibi değil, keşif yapan bir hayvan gibi gezmeli.
Hepsinde azami kuvveti düşürün: tahmin doğru olsa bile hantal bir ajan yakalayamıyor. Zorluk ayarı için güzel bir düğme!
Quiz 2 · arrive
Yavaşlama yarıçapı 100, azami hız 160 olan bir ajan hedefe 25 birim uzaklıktaysa arrive’ın istenen hızı ne kadardır?
Yarıçapın içinde: hız = azami × (mesafe / yarıçap) = 160 × 25/100 = 40. Mesafe 0’a indikçe hız da 0’a iner; yarıçapın dışında 160.
LEVEL 3
Engeller ve yollar
antenler, yol izleme ve sınırları
hareket katmanları
seek ve flee
arrive, pursue, wander
engeller ve yollar
boids ve sürüler
birleştirmek: context steering
kod ve laboratuvarlar
oyunlarda ve kütüphanelerde
Engelden kaçınma ve yol izleme
Anten (feeler)Ajanın önüne, hızıyla orantılı uzunlukta bir “anten” uzat. Anten bir engele değiyorsa, engelin merkezinden uzağa doğru yanal bir kuvvet uygula. Hızlıyken daha uzağa bak (fren mesafesi!). Benzer şekilde duvar takibi ve alanın içinde kalma (containment).
⚠️ Yerel minimumU şeklindeki bir engelin içindeki hedef: kaçınma itiyor, seek çekiyor; ajan dibe sıkışır. Steering yereldir; sadece burnunun ucunu görür. Labirentten çıkmak için yol bulma (A*, Y8) gerekir.
Yol izleme (Reynolds)
Ajanın biraz ilerideki konumunu tahmin et.
Bu noktayı yola izdüşür (en yakın yol noktası).
İzdüşüm yolun “genişliği” içindeyse bir şey yapma; dışındaysa yol üzerinde biraz ileriyi seek et.
A* köşeli bir rota verir; yol izleme köşeleri yumuşatır ve ajanı yolun içinde doğal salınımlarla tutar.
Canlı: yol izleme ve engeller
“Davranış” menüsünden “Path following” seçili. “Engeller + kaçınma”yı açıp Seek’e geçin: anten (kesikli) bir engele değince kırmızıya döner. Fareyi bir engelin tam arkasına koyun: ajan takılıyor mu?
LEVEL 4
Boids ve sürüler
üç basit kural, bir canlı sürü
hareket katmanları
seek ve flee
arrive, pursue, wander
engeller ve yollar
boids ve sürüler
birleştirmek: context steering
kod ve laboratuvarlar
oyunlarda ve kütüphanelerde
Hikâye: Boids (1986) — Batman Returns’ten Half-Life’a 🐦
Craig Reynolds, 1986’da kuş sürülerinin hareketini bir bilgisayar modeliyle taklit etti. Simüle edilen kuşlara “bird-oid” kısaltmasıyla boid dedi.
Her boid sadece yakınındaki birkaç komşuya bakar ve üç kurala uyar. Lider yok, merkezi plan yok — ama ekranda gerçekçi bir sürü belirir.
1987’de SIGGRAPH’ta makaleyle birlikte boids kullanan kısa film Stanley and Stella in: Breaking the Ice gösterildi.
Batman Returns (1992, Tim Burton): yarasa sürüleri ve Gotham sokaklarında yürüyen penguen ordusu, Reynolds’ın boids yazılımının değiştirilmiş hâlleriyle yapıldı. Boids’in ilk uzun metraj filmi.
Half-Life (1998): oyunun sonundaki Xen dünyasında uçan kuş benzeri yaratıklar boids ile hareket eder; oyun dosyalarındaki adları bile “boid”.
💡 Ortaya çıkan davranış (emergence)Reynolds’ın sitesinde: sürü, “basit yerel kurallardan karmaşık küresel davranışın doğmasının” klasik örneği. Kısa vadede tahmin edilebilir (bir saniye sonra aşağı yukarı aynı yöne gider), uzun vadede değil (beş dakika sonra nereye gideceği bilinmez). Yapay yaşam (artificial life) alanının ikonu oldu.
↔ Ayrılma (separation)Komşularına çok yaklaşma. Her yakın komşudan uzağa doğru, yakınlığıyla orantılı bir itme: (ben − komşu) / d².
⇉ Hizalanma (alignment)Komşularınla aynı yöne uç. Komşuların ortalama hızını istenen hız yap.
◎ Bütünleşme (cohesion)Sürüden kopma. Komşuların ortalama konumuna doğru seek.
Her boid sadece bir görüş yarıçapı içindekilere bakar (gerçek kuşlar da yaklaşık 6–7 komşuyu izler).
Üç kuvvet ağırlıklarla toplanır. Ağırlıkları değiştirmek, sürünün karakterini değiştirir: dağınık sinek bulutu, sıkı balık sürüsü, düzenli kaz V’si…
Ek kurallar kolayca eklenir: yırtıcıdan kaç, engelden kaçın, bir hedefe git (başlık animasyonu).
Canlı: boids 🐟
Üç kaydırıcıyı tek tek sıfırlayın. Ayrılma 0: boidler üst üste biner. Hizalanma 0: her biri kendi yönüne. Bütünleşme 0: sürü dağılır.
Fareyi sürünün içine sokun (yırtıcı): sürü yarılıp yeniden birleşiyor. Balık sürülerinin köpekbalığından kaçışı.
Görüş yarıçapını 15’e indirin: küçük gruplar. 120’ye çıkarın: tek dev sürü.
Uzamsal ızgarayı kapatın ve boid sayısını 400 yapın. Üstteki “komşu kontrolü” sayısına bakın: 400 × 399 ≈ 160.000. Izgara açıkken? Bu, BST Geometrik ve Hash sunumlarındaki fikrin aynısı: herkesi herkesle karşılaştırma, sadece yakın hücrelere bak.
🔎 DEMODA DENEYİN
Üç kaydırıcıyı tek tek sıfırlayın. Ayrılma 0: boidler üst üste biner. Hizalanma 0: her biri kendi yönüne. Bütünleşme 0: sürü dağılır.
Fareyi sürünün içine sokun (yırtıcı): sürü yarılıp yeniden birleşiyor. Balık sürülerinin köpekbalığından kaçışı.
Görüş yarıçapını 15’e indirin: küçük gruplar. 120’ye çıkarın: tek dev sürü.
Uzamsal ızgarayı kapatın ve boid sayısını 400 yapın. Üstteki “komşu kontrolü” sayısına bakın: 400 × 399 ≈ 160.000. Izgara açıkken? Bu, BST Geometrik ve Hash sunumlarındaki fikrin aynısı: herkesi herkesle karşılaştırma, sadece yakın hücrelere bak.
🎬 Ara: boids, sıfırdan
Coding Adventure: Boids Sebastian Lague · 8 dk 35 sn · YouTube’da aç
Reynolds’ın üç kuralının (ayrılma, hizalanma, birleşme) 3B’de sıfırdan yazılışı; engellerden kaçınma için ışınlar. Demodaki sürünün adım adım nasıl kurulduğunu görürsünüz.
🤔 İzlerkenVideoda üç kuralın ağırlıkları değişince sürü nasıl davranıyor? Her balık kaç komşusuna bakıyor; bu neden önemli? Engellerden kaçınma bizim “antenler” slaytındaki fikre benziyor mu?
Quiz 3 · boids
Bir boid sürüsünde boidler sürekli birbirinin üstüne biniyor ve tek bir noktada topaklanıyorsa hangi ağırlık çok düşüktür (ya da hangisi çok yüksek)?
Bütünleşme herkesi merkeze çeker; ona karşı koyan tek kuvvet ayrılmadır. Ayrılma zayıfsa ya da bütünleşme baskınsa boidler topaklanır. Hizalanma sadece yönleri eşitler; konum üzerinde doğrudan etkisi yoktur.
LEVEL 5
Birleştirmek: context steering
ağırlıklı toplamın sorunları ve F1 2011
hareket katmanları
seek ve flee
arrive, pursue, wander
engeller ve yollar
boids ve sürüler
birleştirmek: context steering
kod ve laboratuvarlar
oyunlarda ve kütüphanelerde
Davranışları nasıl birleştiririz?
1) Ağırlıklı toplamF = 1,0·seek + 2,0·kaçınma + 1,5·ayrılma → azami kuvvetle kırp. En yaygın ve en basit yol (boids böyle).
2) ÖncelikDavranışları önem sırasına koy (çarpışma > ayrılma > seek). Sırayla sor; anlamlı (sıfırdan büyük) kuvvet üreten ilk davranışı kullan. Acil durumlar diğerlerini bastırır.
3) MelezÖncelik grupları; her grubun içinde ağırlıklı toplam (Millington’ın kitabındaki yaklaşım).
⚠️ Ağırlıklı toplamın sorunları
Birbirini götürme: seek sağa, kaçınma sola → toplam sıfır; ajan engelin önünde durur.
Titreme: iki kuvvet sırayla baskın çıkar, ajan sağa sola sallanır.
Garanti yok: “asla çarpışma” gibi kesin bir kuralı ağırlıkla ifade edemezsiniz; ağırlığı artırırsınız, başka şey bozulur.
Ayar cehennemi: her yeni davranış eskilerin ağırlıklarını yeniden dengelemeyi gerektirir.
Derin hikâye: F1 2011 ve context steering 🏎️
Andrew Fray (Codemasters), Game AI Pro 2’de anlatıyor: yarış arabaları birbirine çok yakın, oyuncu her birini izliyor; çarpışmadan kaçınma ve tutarlı sollama hareketleri çok önemli. Klasik steering davranışları büyüdükçe birbirine bağımlı ve kırılgan hâle geldi.
Fikir: davranışlar artık vektör döndürmez, “bağlam haritası” doldurur. Ajanın etrafında N yön var (ör. 16). Her davranış her yön için iki şey söyler: ilgi (“bu yön hedefe götürür”) ve tehlike (“bu yönde engel var”).
Birleştirme adımı basit: tehlikesi düşük olmayan yönleri maskele, kalanlar arasından ilgisi en yüksek yönü seç.
Davranışlar küçük ve durumsuz; “şu yöne asla gitme” gibi kısıtlar garanti edilir.
Sonuç: F1 2011’de klasik steering’in yerine konduğunda kod tabanı 4000 satır küçüldü; yapay zekâ çarpışmadan kaçınmada ve sollamada daha iyi oldu.
Neden “nasıl” değil “neden”?Fray’ın başlığı “Toward Why, Not How”: davranışlar “şöyle dön” (nasıl) demek yerine “şu yön iyi, şu yön tehlikeli” (neden) der. Kararı tek bir yer verir; davranışlar birbirini götüremez.
Hangi oyunlar için?Fray’a göre klasik steering, oyuncunun tek tek varlıkları izleyemediği sürü/kalabalık oyunlarında hâlâ harika. Oyuncunun yakından izlediği az sayıda varlık (yarış, dövüş, takım arkadaşı) varsa context steering’i düşünün.
Canlı: ağırlıklı toplam vs context steering
Hedef, engelin tam arkasında. “Ağırlıklı toplam”da seek ileri, kaçınma geri iter; simetrik durumda ikisi birbirini götürür ve ajan engelin önünde takılır. Context steering’de her yön için ilgi (yeşil) ve ışınla ölçülen tehlike (kırmızı) var; tehlikeli yönler maskelenir (soluk), kalanlardan hedefe en dönük olan seçilir (turuncu): ajan engelin etrafından dolaşır.
Kalabalıklar: RVO/ORCA ve akış alanları
Karşılıklı kaçınma (RVO / ORCA)İki kişi koridorda karşılaşınca ikisi de “yarı yarıya” kenara çekilir. RVO/ORCA her ajan için “çarpışmaya yol açacak hızları” hesaplar ve geri kalanlardan istenen hıza en yakın olanı seçer. Unreal’ın karakter hareketindeki RVO kaçınması, Unity’nin NavMeshAgent kaçınması ve Godot’nun NavigationAgent kaçınması bu aileden yerel kaçınma sistemleridir. (Ayrıntı: Sunshine-Hill, Game AI Pro 3, 19. bölüm.)
Akış alanları (flow fields)Binlerce birim aynı hedefe gidiyorsa her biri için ayrı A* yapmak israf. Haritanın her hücresine bir kez “hedefe şu yönden gidilir” oku yaz; birimler sadece bulundukları hücrenin okunu seek eder.
Supreme Commander 2 (Elijah Emerson, Game AI Pro, 23. bölüm): akış alanı karoları ile kalabalık yol bulma ve yönlendirme.
Fieldrunners 2 (mobil kule savunma, Game AI Pro, 24. bölüm): akış alanı + steering ile mobil cihazda binlerce birim.
Quiz 4 · birleştirmek
Seek hedefe doğru (sağa) 100 birimlik, kaçınma tam tersine (sola) 100 birimlik kuvvet üretiyor. Ağırlıklı toplamda (ağırlıklar 1) ne olur?
Toplam sıfırdır: ajan ne ileri ne geri gider (yerel minimum). Ağırlıklı toplamın klasik sorunu budur. Öncelik sistemi ya da context steering, bu durumda tehlikeli yönü maskeleyip yan yönleri değerlendirerek çıkış bulabilir; gerçek labirentlerde ise yol bulma gerekir.
v.normalized * s · v.setMag(s) · v.scale_to_length(s)
kırp
en fazla m uzunluk
Vector2.ClampMagnitude(v, m) · v.limit(m)
Hatırlatma (Y0)Normalize etmeden önce uzunluğun 0 olmadığından emin olun: sıfıra bölme! Unity normalized sıfır vektörde sıfır döndürür; elle yazarken kontrol edin.
Neden sınıf?Ajanın konum, hız, azami hız/kuvvet gibi verilerini ve davranışlarını tek bir Vehicle (araç) sınıfında toplamak, sürüde yüzlerce kopyasını oluşturmayı kolaylaştırır. Reynolds ve “Nature of Code” bu adı kullanır.
Vehicle sınıfı (1/2)
Vehicle sınıfı (2/2)
p5.js örneği “kare başına” birimler kullanır (Nature of Code tarzı); Unity ve pygame örnekleri saniye ve dt ile çalışır. Kendi oyununuzda dt’li hâli tercih edin (Y0: kare hızından bağımsızlık).
Sürü (flocking)
Bu kod her boidi her boidle karşılaştırır: O(n²). Demodaki gibi bir ızgara (hash tablosu: hücre → boid listesi) ile sadece komşu hücrelere bakın. Unity’de binlerce boid için Jobs/Burst ya da ECS kullanılır.
🎒 Kod sözlüğü
createVector · p5.Vector.sub · .setMag · .limit
p5.js vektörleri
Oluştur · çıkar (yeni vektör) · uzunluğu ayarla · uzunluğu kırp
Unity’de uzunluğu en fazla m yapan hazır fonksiyon
transform.forward = velocity
yöne bakma
Nesneyi gittiği yöne çevirir
pygame.Vector2 · scale_to_length
pygame vektörü
2B vektör sınıfı · uzunluğu ayarla
O(n²)
karesel karmaşıklık
n boid için n·(n−1) karşılaştırma (Algoritma Analizi sunumu)
📦 Tam kod: p5.js’te avcı ve sürü
Bütün steering bu üç parçadır: davranış istenen hızı söyler, applyDesired onu kuvvete çevirir, update kuvveti harekete çevirir. Yeni davranış = istenen hızı hesaplayan yeni bir fonksiyon.
🎮 Çalıştırın, kopyalayın, bozun
▶ Eksiksiz örneği aç — yaklaşık 90 satır: fareye arrive ile gelen bir avcı ve ondan kaçan 70 balıklık bir sürü.
Deneyin:
Avcıda arrive yerine seek yazın: fareyi sabit tutunca ne oluyor?
Ayrılma ağırlığını (1.6) sıfırlayın. Sonra bütünleşmeyi (0.9).
Avcının azami kuvvetini 420’den 60’a indirin: balıklar artık kolayca kaçıyor mu?
Balıklara “fareden kaç” yerine “fareye git” yazın: balık yemi!
🌱 Isınma kodu: direksiyon kuvveti
Bütün steering davranışlarının ortak son satırı. Sağa 180 hızla giderken sola 180 gitmek istiyorsanız direksiyon [-360, 0] çıkar: “önce fren, sonra geri”. Aynı yöne zaten gidiyorsanız [0, 0]: düzeltmeye gerek yok.
🌱 Isınma kodu: vektörü kırp (limit)
“Azami hız” ve “azami kuvvet” bu fonksiyonla uygulanır; p5.js’te hazırı v.limit(max). Karakterin kişiliği bu iki sınırdadır: hızlı ama hantal bir tank, yavaş ama çevik bir kedi.
🧪 Canlı laboratuvar: seek ve arrive
Seek hazır; simülasyon arrive’ı kullanıyor. Başlangıçta ajan hedefin etrafında yörüngeye girer. Arrive’ı tamamlayın: sarı çemberin içinde yavaşlayıp hedefte durmalı. Testler 5 seek + 5 arrive durumu dener (mesafe 0 dahil).
🐍 Laboratuvar: ayrılma kuvveti
Neden d²? (me − komşu) vektörünün uzunluğu zaten d; d²’ye bölünce sonuç yön / d olur: yakın komşu güçlü, uzak komşu zayıf iter. Komşu yoksa [0, 0].
🐍 Laboratuvar: hizalanma
Adımlar: topla → n’e böl → uzunluğu hesapla (math.hypot) → sıfır değilse yönü bul ve max_speed ile çarp. Testte birbirini götüren iki hız da var.
Yol bulma + seek/arrive benzeri hareket + diğer ajanlardan yerel kaçınma (kalitesi obstacleAvoidanceType ile). Sürü, wander gibi davranışlar yok; kendi steering’inizle birleştirebilirsiniz.
Package Manager → AI Navigation; ajana NavMeshAgent bileşeni
Web oyunları için YZ kütüphanesi: Reynolds’ın steering davranışlarının çoğu, ayrıca FSM, hedef güdümlü ajanlar, algı, yol bulma. Three.js ile örnekler.
Daniel Shiffman’ın kitabının “Autonomous Agents” bölümü: bu sunumdaki her davranışın adım adım p5.js kodu ve videoları.
Tarayıcıda oku, p5.js editöründe dene
🧩 Projenize steering eklerken
Önce motorun ajanını deneyin: NavMeshAgent / CharacterMovement + RVO çoğu insansı karakter için yeter.
Kendi steering’iniz: uçan/yüzen yaratıklar, araçlar, uzay gemileri, sürüler, “canlı” dolaşma gibi motorun yapmadığı şeyler için.
Fizik mi, kinematik mi? Rigidbody kullanıyorsanız kuvveti AddForce ile verin; kinematikse bu sunumdaki gibi hızı kendiniz entegre edin. İkisini karıştırmayın.
Locomotion ile bağlayın: hız büyüklüğünü animasyondaki “Speed” parametresine verin (yürü/koş geçişi), yönü karakterin dönüşüne. Ayak kaymasını önlemek için animasyon hızına uyun.
Ayar araçları: azami hız/kuvvet ve ağırlıkları Inspector’da açın, oyun çalışırken ayarlayın; vektörleri Gizmos ile çizin (demodaki gibi).
⚙️ PerformansSteering ucuz; pahalı olan komşu arama. Uzamsal ızgara/hash, kuadtree ya da motorun fizik sorguları (OverlapSphere) kullanın. Binlerce birim için Unity Jobs + Burst / ECS, Unreal Mass.
Sık hataSteering’i Update’te, fiziği FixedUpdate’te yapıp aynı hıza iki yerden yazmak. Bir yer seçin. Ayrıca dt’siz (kare başına) kodu yüksek FPS’de çalıştırınca her şey hızlanır (Y0).
🤖 Bu konuyu bir YZ kod asistanıyla yazarken
Sık yapılan hatalar — kontrol edin
Normalize’dan önce sıfır uzunluk kontrolünü unutmak (NaN pozisyonlar!)
İstenen hızı direksiyon kuvveti sanmak (“− velocity” unutulur)
Azami kuvveti uygulamamak: ajan anında döner, “steering” etkisi kaybolur
Kuvvetleri her kare sıfırlamamak (p5.js stili acc)
Boidlerde O(n²) döngü: 500 boidde oyun yavaşlar
İyi bir istek (prompt) örneği
“Unity 6, C#, 3D ama yerde (y sabit). Kinematik bir Vehicle bileşeni yaz: maxSpeed, maxForce, FixedUpdate’te dt ile Euler entegrasyonu. Davranışlar: Seek, Arrive (slowRadius), Pursue (T = mesafe / maxSpeed, en fazla 1.5 sn), Wander (çember yarıçapı, mesafe, sapma). Birleştirme: öncelikli — önce engel kaçınması (ileriye SphereCast), sonra diğerlerinin ağırlıklı toplamı. OnDrawGizmos ile hız (mavi), istenen hız (yeşil) ve kuvvet (kırmızı) oklarını çiz. Hız büyüklüğünü Animator “Speed” parametresine gönder.”
Hangi davranışları, hangi birleştirme yöntemiyle (ağırlık/öncelik) istediğinizi yazın
Birim sistemini belirtin: kare başına mı saniye başına mı (dt)
Rigidbody mi kinematik mi kullanılacağını söyleyin
Debug için Gizmos ile vektör çizimi isteyin
Komşu arama için ızgara/fizik sorgusu isteyin
🔬 Araştırma ucu
Yaya dinamiğiHelbing & Molnár’ın “sosyal kuvvet modeli” (1995): yayaları hedefe çeken ve birbirinden/duvarlardan iten kuvvetlerle modellemek — steering’in bilimsel kuzeni. Tahliye simülasyonlarında, stadyum ve metro tasarımında kullanılır.
Öğrenilen hareketUnity ML-Agents gibi araçlarla ajanlar, ödül fonksiyonuyla (hedefe ulaş, çarpışma) hareket etmeyi öğrenebilir (Y13). Elle yazılmış steering ile öğrenilmiş politikanın karşılaştırılması güzel bir bitirme projesi.
Kişilikli kalabalıklarAynı kalabalıkta acelesi olan, turist, grup hâlinde yürüyen ajanlar: farklı azami hız, kişisel alan (ayrılma yarıçapı) ve hedef davranışları. Açık dünya oyunlarının sokaklarını “canlı” gösteren şey bu çeşitlilik.
💬 Tartışma soruları
Yanınızdakiyle 2 dakika konuşun, sonra sınıfça tartışalım
Bir zombi, bir yarış arabası ve bir sinek için azami hız ve azami kuvvet değerlerini (düşük / orta / yüksek) nasıl seçerdiniz? Hangisi “korkutucu”, hangisi “sinir bozucu” hissettirir?
Boids’te lider yok ama sürü “bir yere gidiyor” gibi görünür. Bir filmde ya da oyunda gördüğünüz bir kalabalığın/sürünün böyle yapıldığını şimdi düşününce tahmin edebiliyor musunuz?
Steering “yereldir”: ajan sadece burnunun ucunu görür. U biçimli bir duvarın içindeki hedefe neden ulaşamaz? Bunu çözmek için ne eklemek gerekir?
F1 2011 ekibi klasik steering’i atıp context steering’e geçti ve 4000 satır kod sildi. Bir sistemi “daha akıllı” yapmanın yolu bazen neden daha az kod yazmaktır?
🚀 Proje ve araştırma önerileri
[kolay]Akvaryum — p5.js’te balık sürüsü + bir köpekbalığı (pursue) + yem (seek). Ağırlıkları kaydırıcıyla ayarlanabilir yapın.
[kolay]Uzay gemisi — Klavyeyle kontrol edilen oyuncu ve onu pursue ile kovalayan, evade ile mermilerden kaçan düşman gemileri.
[orta]Çoban köpeği — Koyunlar boids, köpek oyuncu (ya da YZ). Koyunlar köpekten flee eder; amaç sürüyü ağıla sokmak. Reynolds’ın kovboy benzetmesinin oyunu!
[orta]Unity sürüsü — 500 kuş, ızgara ile komşu arama; profiler ile O(n²) sürümle karşılaştırın.
[zor]Context steering yarışı — Basit bir 2B yarış: araçlar context steering ile çarpışmadan sollama yapsın; ağırlıklı toplam sürümüyle çarpışma sayısını karşılaştırın.
[araştırma]Tahliye simülasyonu — Bir binanın planında sosyal kuvvet modeli + akış alanı ile tahliye süresini ölçün; kapı genişliği nasıl etkiliyor?
Neler öğrendik? 🎒
Üç katman: karar → yönlendirme → hareket.
Direksiyon = istenen hız − mevcut hız, azami kuvvetle kırpılır.
Adı geçen oyunu tanımıyorsanız: oyuncuların kullandığı wiki sayfası ve oyunu kısaca gösteren bir video. ▶ video slaydın üstünde açılır (Esc ile kapanır); 🎯 işaretli bağlantılar doğrudan bu sunumdaki konuya gider.
Half-Life1998 · nişancı
Hikâyeyi ara sahnesiz anlatan, türü değiştiren nişancı; asker timleri birlikte hareket eder.