🎮 hangi oyunda, nasıl kullanıldı (gerçek hikâyeler)
🧰 kütüphaneler: nasıl eklenir, ne yapar, ne yapmaz
🤖 YZ kod asistanıyla çalışırken dikkat
🚀 proje ve araştırma önerileri
Bölümün yol haritası 🗺️
Sıra, resmî haftalık planı izler ama ön koşulları en aza indirmek için yeniden düzenlendi: karar verme konuları bir arada, A* steering’den sonra (hareket bilgisini kullanır), taktik YZ algılamadan sonra. Her sunumun başında “🎯 bilmeniz gerekenler” slaytı var.
🎯 Bu konu için bilmeniz gerekenler
Yeşil = gerekli · kesikli = faydalı ama şart değil. Tıklayınca ilgili sunuma gider.
Neden?Bu sunum bölümün “sıfır noktası”. Lise matematiği (koordinat düzlemi, Pisagor, sinüs/kosinüs) yeter; geri kalanını burada adım adım kuruyoruz.
🧰 Kodlamadan korkuyorsanızBütün formülleri ezberlemeniz gerekmiyor. Her vektör işleminin oyundaki anlamını (mesafe, yön, “önümde mi?”, “sola mı sağa mı?”) anlamanız yeterli; kodu Unity ve p5.js zaten hazır veriyor.
Mini sözlük
vector · magnitude
vektör · büyüklük (uzunluk)
Yönü ve büyüklüğü olan nicelik: (x, y)
normalize · unit vector
normalleştirmek · birim vektör
Uzunluğu 1 olan, sadece yön taşıyan vektör
dot product
nokta (iç) çarpım
İki yönün ne kadar aynı olduğunu söyleyen sayı
cross product
çapraz (dış) çarpım
2B’de: hedef solda mı sağda mı?
radian · degree
radyan · derece
π radyan = 180°
game loop · frame
oyun döngüsü · kare
Girdi → güncelle → çiz, saniyede onlarca kez
delta time (dt)
kare süresi
Önceki kareden bu yana geçen süre (saniye)
lerp (linear interpolation)
doğrusal ara değer
İki değer arasında t oranında bir nokta
LEVEL 0
Vektörler
konum, yön, hız: hepsi bir ok
vektörler
nokta ve çapraz çarpım
açılar
zaman ve oyun döngüsü
hareket ve hassasiyet
Unity ve p5.js iskeleti
araçlar ve YZ asistanı
Önce günlük hayattan: “3 sokak doğu, 2 sokak kuzey” 🗺️
Arkadaşınız kafeyi tarif ediyor: “Evden 3 sokak doğu, 2 sokak kuzey.” Bu iki sayıya birlikte vektör denir: (3, 2). Bir vektör “nereden nereye, ne kadar” bilgisini taşıyan bir oktur.
soru
elle hesap
kafe evden nerede?
fark: (3 − 0, 2 − 0) = (3, 2)
kuş uçuşu ne kadar uzak?
uzunluk: √(3² + 2²) = √13 ≈ 3,6
pusula hangi yönü göstersin?
normalize: (3, 2) ÷ 3,6 ≈ (0,83 ; 0,55)
Oyunda da aynı: nöbetçi (1, 1)’de, oyuncu (4, 3)’te. Fark yine (3, 2), uzaklık yine 3,6. Bu sunumdaki her şey bu üç satırın üstüne kurulu.
Oyunda her şey bir vektör
Konumposition: “orijinden buraya ok”: (3, 2)
Hızvelocity: “her saniye bu kadar kay”: (120, 0) piksel/sn
Yöndirection: sadece nereye — uzunluğu 1
Kuvvet / ivme: hızı değiştiren ok (steering sunumu!)
🎮 Bir NPC’nin her karede sorduğu sorular
Oyuncu ne kadar uzakta? → çıkarma + uzunluk
Hangi yöne gitmeliyim? → normalize
Oyuncu önümde mi, arkamda mı? → nokta çarpım
Sola mı sağa mı döneyim? → çapraz çarpım
Bu sunumun tamamı bu dört sorunun cevabı.
Vektör oyun alanı — kendiniz deneyin
Mesafe ve yön — kod
🎒 Unity’de Vector3 bir yapıstruct: atayınca kopyalanır (referans değil!). transform.position.x = 5; çalışmaz — önce kopyayı alıp değiştirip geri atarsınız.
🎒 Ön bilgi: iki koordinat sistemi
p5.js’te y aşağı artar; Unity’de yukarı.
Unity 3B’de zemin x–z düzlemi; y yükseklik. 3B bir oyunda 2B YZ yazarken y’yi sıfırlamayı unutmayın: toPlayer.y = 0;
Açılar: Unity transform.eulerAnglesderece; Mathf.Sin/Cos ve p5 varsayılanı radyan.
YZ asistanları bu farkları sık karıştırır: “p5.js” ya da “Unity 2D, y yukarı” diye açıkça yazın.
🔗 Başka gözle: etkileşimli anlatımlar ve yazılar
Aynı konuyu başka bir anlatımla, kendi elinizle oynayarak görmek çok işe yarar. Kartlar yeni sekmede açılır; çoğu İngilizce ama görsel ve etkileşimli.
Düşman (2, 3) noktasında, oyuncu (5, 7) noktasında. Aralarındaki mesafe kaç birimdir?
Fark vektörü (5 − 2, 7 − 3) = (3, 4). Uzunluğu √(3² + 4²) = √25 = 5. Klasik 3-4-5 üçgeni: Pisagor oyunlarda her karede binlerce kez çalışır.
LEVEL 1
Nokta ve çapraz çarpım
“önümde mi?” ve “solumda mı?”
vektörler
nokta ve çapraz çarpım
açılar
zaman ve oyun döngüsü
hareket ve hassasiyet
Unity ve p5.js iskeleti
araçlar ve YZ asistanı
Önce sezgi: oyuncu nöbetçinin önünde mi, arkasında mı?
Nöbetçi sağa bakıyor: ileri = (1, 0). Üç oyuncunun yerini nöbetçiye göre yazalım ve tek bir işlem yapalım: x’leri çarp, y’leri çarp, topla.
oyuncu
fark
ileri · fark
anlamı
A
(3, 1)
1·3 + 0·1 = 3
+ önünde
B
(0, 2)
1·0 + 0·2 = 0
tam yanında
C
(−2, 1)
1·(−2) + 0·1 = −2
− arkasında
Bu işlemin adı nokta çarpım. Sonucun işareti “önde mi, arkada mı?” sorusunu cevaplar. Nöbetçi yukarı dönerse (ileri = (0, 1)) aynı hesap B için 2, A ve C için 1 verir: artık en çok önündeki B.
Nokta çarpım dot product
\( a \cdot b = a_x b_x + a_y b_y = |a|\,|b|\cos\theta \)
İki birim vektör için sonuç = aradaki açının kosinüsü
1: aynı yön · 0: dik · −1: zıt yön
Sadece çarpma ve toplama: çok ucuz (karekök, sinüs yok)
🎬 Ara: nokta çarpım, iki dakikada
The Dot Product – A Visual Explanation Freya Holmér · 1 dk 50 sn · YouTube’da aç
Az önce elle yaptığımız hesabın görsel hâli: bir vektörün öbürünün üstüne düşen “gölgesi”. Freya Holmér oyun geliştiricilere matematik anlatan en iyi kaynaklardan biri; dört saatlik tam dersi kaynaklar slaytında.
🤔 İzlerkenVideoda vektörlerden biri birim uzunlukta olunca sonuç neye dönüşüyor? Gölge ne zaman negatif oluyor? Bunu A, B, C tablosundaki hangi satır gösteriyordu?
🎒 Neden cos(FOV/2)? Koni ileri yönün iki yanına FOV/2 kadar açılır. Açıyı hesaplamak (acos) yerine kosinüsleri karşılaştırmak daha hızlıdır: açı büyüdükçe kosinüs küçülür.
Çapraz çarpım: sola mı, sağa mı?
\( a \times b = a_x b_y - a_y b_x \) (2B’de tek sayı)
İşareti, b’nin a’nın hangi tarafında olduğunu söyler
🎮 Taret / araç YZ’si: “hedef solumda → sola dön”
3B’de iki vektöre dik üçüncü bir vektör verir: yüzey normali, “yukarı” yönü
⚠️ İşaret tuzağıEkran (y aşağı) ile Unity (y yukarı) arasında sol/sağ yer değiştirir. Emin değilseniz test edin: hedefi bilerek sola koyup işarete bakın.
Quiz 2 · nokta çarpım
NPC’nin ileri yönü (1, 0). Normalize edilmiş “oyuncuya yön” vektörü (−0,8; 0,6). Nokta çarpım ne söyler?
1·(−0,8) + 0·0,6 = −0,8. Negatif → açı 90°’den büyük → oyuncu NPC’nin arkasında. Bu bilgi “sırttan bıçaklama” (backstab) mekaniğinde kullanılır: dot < −0,7 ise kritik vuruş!
🌱 Isınma kodu: iki nokta arası mesafe
Tek satır değişecek. İpucu: Math.sqrt(dx * dx + dy * dy) ya da kısaca Math.hypot(dx, dy). Quiz 1’deki (2, 3) → (5, 7) örneği 5 vermeli.
🌱 Isınma kodu: hedef arkamda mı?
Nokta çarpım negatifse açı 90°’den büyüktür: hedef arkadadır. Burada normalize etmeye gerek yok — yalnızca işarete bakıyoruz. (Sırttan bıçaklama mekaniğinin ilk satırı.)
🧪 Kod laboratuvarı: görüş konisinde mi?
İki hata var: (1) vektörler normalize edilmeden karşılaştırılıyor, (2) Math.cos radyan ister. Bonus: hedef tam nöbetçinin üstündeyse (d = 0) ne olur? NaN’ı engelleyin.
atan2(y, x): bir vektörün açısı (−π … π). “Hedefe dönmek için hangi açıya bakmalıyım?”
Açıdan yön: (cos θ, sin θ)
Derece ↔ radyan: rad = deg × π / 180
Açı farkı tuzağı: 350° ile 10° arası fark 340° değil, 20°! Farkı hep −180…180 aralığına getirin (Unity: Mathf.DeltaAngle)
Unity 3B’de dönüşler quaternion: Quaternion.LookRotation(dir) ve Quaternion.RotateTowards kullanın, açılarla uğraşmayın
⚙️ Performans notu: karekök almayın
“Oyuncu 10 birimden yakın mı?” sorusu için distance < 10 yerine distanceSquared < 100 yazın. Uzunluk √ ister; karşılaştırmada iki tarafın karesini almak sonucu değiştirmez.
Unity: (a - b).sqrMagnitude < r * r
p5.js: p5.Vector.sub(a, b).magSq() < r * r
Python: dx*dx + dy*dy < r*r
1000 düşman × 60 kare = saniyede 60.000 karekökten kurtuldunuz. (Öncelik Kuyrukları ve En Kısa Yollar sunumlarındaki “karşılaştırmak için kök gerekmez” fikri.)
📜 Quake III Arena (1999): 0x5F3759DF
Karekök o yıllarda o kadar pahalıydı ki Quake III’ün kaynak kodunda vektör normalleştirmek için ünlü bir hile var: sayının bitlerini tam sayı gibi okuyup “sihirli sabit” 0x5F3759DF’ten çıkaran ve 1/√x’i yaklaşık %1 hatayla, bölme yapmadan veren dört satır. Yanındaki yorum satırı meşhurdur: programcı bile nasıl çalıştığına şaşırmış. Çoğu kişi John Carmack’in yazdığını sanır; kendisi yazmadığını söylüyor, hilenin izi 1980’lere kadar sürülüyor.
Bugün işlemcilerde bunun için hazır komut var; hileyi kullanmayın ama dersi alın: her karede binlerce kez çalışan kodda en ucuz işlemi seçin.
LEVEL 3
Zaman ve oyun döngüsü
delta time: her bilgisayarda aynı hız
vektörler
nokta ve çapraz çarpım
açılar
zaman ve oyun döngüsü
hareket ve hassasiyet
Unity ve p5.js iskeleti
araçlar ve YZ asistanı
Oyun döngüsü game loop
Saniyede 30–144 kez döner. Her tura kareframe denir.
60 FPS → bir karenin bütçesi 16,6 ms. YZ, fizik, çizim, ses… hepsi bu sürede!
Unity: Update() her karede, FixedUpdate() sabit aralıkla (fizik, varsayılan 0,02 sn), LateUpdate() çizimden hemen önce (kamera).
p5.js: draw() her karede. Python/pygame: kendi while döngünüz.
Önce “deltaTime kullan” kapalıyken izleyin: 144 FPS’lik bilgisayardaki top yarışı açık ara kazanıyor. Kutuyu işaretleyin: ikisi aynı hızda koşar. Kural: “kare başına” değil, “saniye başına” düşünün ve dt ile çarpın.
📜 Gerçek hikâyeler: kare hızına bağlı oyun mantığı
Dark Souls II (PC, 2014–2015)Silahların aşınması kare sayısına bağlı yazılmıştı. Konsolda 30 FPS’te sorun yoktu; 60 FPS’te çalışan PC sürümünde silahlar iki kat hızlı aşındı (özellikle cesetlere vurunca). Yaklaşık bir yıl sonra bir yamayla düzeltildi.
Need for Speed Rivals (PC, 2013)Simülasyon 30 FPS’e kilitliydi. Oyuncular ayar dosyasından kilidi kaldırınca bütün oyun iki kat hızlandı: arabalar, polisler, fizik. Topluluk, simülasyon hızını ayrı bir parametreyle 60’a eşitleyerek çözdü.
Ders: YZ zamanlayıcıları (“3 saniye sonra saldır”), soğuma süreleri, hareket hızları — hepsi saniye cinsinden olmalı. Kaynaklar: PC Gamer haberi ve Blur Busters forum başlığı (okuma listesinde).
Gizli tuzak: lerp ile yumuşatma
Çok sevilen x = lerp(x, hedef, 0.1) “her karede yolun %10’unu git” demek → yüksek FPS’te daha hızlı yaklaşır. Doğrusu: 1 − exp(−hız × dt) oranı. Jonas Tyroller’ın “Dear Game Developers, Stop Messing This Up!” videosu tam bu konu (kaynaklarda).
Kare hızından bağımsız kod
🎬 Ara: lerp ve dt hatası
Dear Game Developers, Stop Messing This Up! Jonas Tyroller · 22 dk 19 sn · YouTube’da aç
“Gizli tuzak: lerp” demosunda gördüğümüz hatanın uzun hikâyesi: lerp(x, hedef, 0.1) neden kare hızına bağlı, 1 − exp(−k·dt) nereden çıkıyor, oyunlarda nerelerde karşımıza çıkıyor. İlk 8 dakika ders için yeterli.
🤔 İzlerkenVideoda yanlış formül 30 FPS’te ve 144 FPS’te nasıl farklı davranıyor? Doğru formül hangi matematik fikrinden çıkıyor? Kendi oyununuzda “her karede %10 yaklaş” yazdığınız bir yer var mı?
Quiz 3 · zaman
Bir düşman Update() içinde transform.position += dir * 0.1f; ile hareket ediyor. 30 FPS ve 120 FPS’lik iki bilgisayarda ne olur?
Kare başına 0,1 birim: 30 FPS’te saniyede 3, 120 FPS’te saniyede 12 birim. Doğrusu dir * speed * Time.deltaTime: o zaman ikisi de saniyede speed kadar gider.
LEVEL 4
Hareket ve hassasiyet
hedefe yürümek ve kayan nokta tuzakları
vektörler
nokta ve çapraz çarpım
açılar
zaman ve oyun döngüsü
hareket ve hassasiyet
Unity ve p5.js iskeleti
araçlar ve YZ asistanı
🧪 Canlı laboratuvar: hedefe yürü
Bu kod hedefe gidiyor ama hız mesafeye bağlı (uzaktayken roket, yakınken kaplumbağa). Yönü normalize edip speed * dt kadar yürüyün. Hedefi geçmesin (adım ≥ mesafe ise doğrudan hedefe konun) ve mesafe 0 iken NaN üretmesin. Çalıştırınca fareyi sağdaki kutuda gezdirin.
📜 Kayan nokta floating point hikâyeleri
Minecraft “Far Lands” (2010–2011)Merkezden ~12,5 milyon blok uzaklaşınca arazi üretecinin gürültü hesabındaki sayılar sığdıkları türü aştı (taşma) ve dev, delikli “duvar”lar çıktı; daha da uzakta float hassasiyeti yüzünden hareket titremeye başlıyordu. Bir oyuncu (KurtJMac) yıllarca oraya yürüyerek gitmeyi yayınladı. Beta 1.8’de arazi üreteci değişince kayboldu.
Kerbal Space Program “Derin Uzay Krakeni”Gemi Güneş’ten çok uzaklaşınca parçaların konumları tek duyarlıklı (float) sayılarla yeterince hassas hesaplanamıyor, gemi görünmez bir canavar saldırmış gibi parçalanıyordu. Çözüm: kayan orijinfloating origin — oyuncu belli bir mesafe gidince bütün dünyayı kaydırıp oyuncuyu tekrar (0, 0, 0)’a almak.
konum (float)
1
1.000
100.000
1.000.000
12.550.000
16.777.216
bir sonraki sayıya en küçük adım
0,00000012
0,00006
0,008
0,06
1
2
32 bitlik float’ta sayı büyüdükçe “ızgara” seyrekleşir: 16 milyonun ötesinde tek sayılar bile yazılamaz. Uzay oyununda 1 metrelik adım, gemi parçalarının titremesi demektir.
⚙️ YZ kodu için dersif (pos == target) asla yazmayın: iki float neredeyse hiç tam eşit olmaz. if ((pos - target).sqrMagnitude < 0.01f) gibi bir tolerans epsilon kullanın. Büyük açık dünya oyunlarında (100 km+) YZ’nin konumları da kayan orijinden etkilenir.
FixedUpdate(): sabit aralık — fizik ile hareket (Rigidbody)
OnTriggerEnter: biri tetik alanına girdi (“duydum!”)
OnDestroy(): yok edilirken temizlik
🎒 Ön bilgiGameObject = sahnedeki nesne; Component = ona takılan yetenek (Transform, Rigidbody, sizin betiğiniz). public alanlar Inspector’da görünür: tasarımcı hızı kod açmadan ayarlar.
İyi bir YZ kodu düzeni: beyin ve kaslar
Algılamaperception: “ne görüyorum, ne duyuyorum?” → bilgileri bir kara tahtayablackboard yaz
Hareketmovement: “oraya nasıl giderim?” → steering, A*, NavMesh
Animasyon/ses: yapılanı göster
Bu katmanlara ayırmak, örneğin karar sistemini FSM’den davranış ağacına çevirirken hareket kodunu hiç değiştirmemenizi sağlar. Ian Millington’ın “AI for Games” kitabındaki model.
⚙️ Zamanlama hileleri
Karar her karede değil, saniyede 5–10 kez verilebilir (insan da o kadar hızlı karar vermez) → Performans sunumu
Unity Coroutine: yield return new WaitForSeconds(0.5f); ile “yarım saniye bekle, sonra tekrar düşün”
Rastgele küçük gecikmeler: 20 düşmanın aynı karede aynı şeyi yapması robotik görünür
“Unity 6, 3D, C#. Bir Guard bileşeni yaz: oyuncu 10 birim içinde ve 90° görüş konisindeyse ona saniyede 3 birim hızla yürüsün, y eksenini yok saysın, dönüşü saniyede en fazla 180° olsun. deltaTime kullan, sıfır vektör durumunu kontrol et, kodu satır satır Türkçe yorumla.”
Motoru ve sürümü yazın (Unity 6, 2D / 3D)
Koordinat sistemini söyleyin (y yukarı mı aşağı mı?)
Hızların birimini isteyin (birim/saniye) ve deltaTime ile çarpılmasını şart koşun
Kodu çalıştırıp kenar durumlarını deneyin: hedef tam üstteyken, çok hızlıyken
💬 Tartışma soruları
Yanınızdakiyle 2 dakika konuşun, sonra sınıfça tartışalım
Bir oyunu hem eski hem yeni bir bilgisayarda oynadınız ve yenisinde her şey “hızlı çekim” gibi. Kodda ne unutulmuş olabilir? Oyuncu olarak bunu başka hangi belirtilerden anlarsınız?
“Oyuncu önümde mi?” sorusunu açı hesaplayarak (atan2, acos) da cevaplayabiliriz. Oyun motorları neden nokta çarpımı tercih ediyor?
Dark Souls II’deki silah aşınması hatası konsolda neden hiç görülmedi? Bu size test hakkında ne söylüyor?
Minecraft’ın Far Lands’i bir hataydı ama oyuncular onu sevdi. Bir hatayı düzeltmemek ne zaman doğru karar olabilir?
🚀 Proje ve araştırma önerileri
[kolay]Fareyi izleyen taret — p5.js’te bir taret, atan2 ile fareye dönsün; dönüş hızı sınırlı olsun (saniyede 90°).
[kolay]Görüş konili nöbetçi — Dönen bir nöbetçi; fare konisine girince kırmızı olsun. FOV ve menzil kaydırıcıyla ayarlansın.
[orta]Sırttan bıçaklama — Oyuncu düşmanın arkasından (dot < −0,7) vurursa 3 kat hasar. Unity’de 3B, y yok sayılarak.
[orta]FPS testi — Aynı sahneyi 30 ve 144 FPS’e kilitleyip (Application.targetFrameRate) hareket ve zamanlayıcıların aynı kaldığını gösteren bir test yazın.
[araştırma]Kayan orijin — KSP’nin Krakensbane sistemini ve Unity’de floating origin uygulamalarını araştırıp 1 sayfalık özet yazın.
[araştırma]Freya Holmér serisi — “Math for Game Devs” serisinin ilk iki bölümünü izleyip öğrendiğiniz 5 vektör hilesini oyun örnekleriyle sunun.
Neler öğrendik? 🎒
soru
araç
Unity
p5.js
ne kadar uzak?
çıkarma + uzunluk
(b-a).magnitude
p5.Vector.dist(a,b)
hangi yöne?
normalize
v.normalized
v.normalize()
önümde mi? görüyor mu?
nokta çarpım
Vector3.Dot
a.dot(b)
sola mı sağa mı?
çapraz çarpım
Vector3.Cross
a.cross(b)
hangi açı?
atan2
Mathf.Atan2
atan2 / v.heading()
her bilgisayarda aynı hız
delta time
Time.deltaTime
deltaTime / 1000
🎮 Bu sunumdaki oyunlar
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.
Quake III Arena1999 · arena nişancı
Hızlı tempolu çok oyunculu nişancı; kaynak kodu açık.