Bölüm 3 · Sunum 1

deltaTime: her bilgisayarda aynı hız

Hareketi frame sayısına değil, geçen gerçek süreye bağlayacağız.

Sorun: x += 3deltaTime nedir?Piksel / saniyeHareketli top

Aynı oyun, iki bilgisayar. Birinde karakter iki kat hızlı koşuyor.

Kod aynı, oyun aynı. Fark nereden geliyor olabilir?

İpucu: geçen dersin son konusu.

x += 3 hızı frame sayısına bağlar

BilgisayarFPSSaniyede yol
Hızlı~6060 × 3 = 180 piksel
Yavaş~3030 × 3 = 90 piksel

Her frame 3 piksel ekliyoruz. Saniyede kaç frame üretilirse o kadar yol alınır.

SonuçAynı kod, farklı frame hızında farklı oyun hızı üretir. Oyuncunun deneyimi bilgisayardan bilgisayara değişir.

İki bilgisayarı yan yana koysak

İki topun kodu da aynı: x += 3. Alttaki bilgisayar yalnızca yarısı kadar frame üretebiliyor.

Bu hata gerçek oyunlarda da yaşandı

Dark Souls II PC60 FPS’te oynayanların silahları, 30 FPS’te oynayanlara göre iki kat hızlı yıpranıyordu. Yıpranma hesabı frame sayısına bağlıydı.
Skyrim, Fallout 4Fizik hesabı frame hızına bağlı. Çok yüksek FPS’te eşyalar masalardan fırlar, karakterler tuhaf davranır.
Space Invaders 1978Uzaylılar azaldıkça işlemcinin yükü hafifliyor, oyun hızlanıyordu. Bu “hata” oyunun en sevilen özelliği oldu.

Bugünkü konu, profesyonel stüdyoların da zaman zaman takıldığı bir konu.

Hızlı nesnelerde sorun büyür: mermi

Frame başına küçük adım: çarpar Frame başına büyük adım: üstünden atlar

Mermi frame başına 15 piksel gitsin:

  • 30 FPS’te saniyede 450 piksel.
  • 60 FPS’te saniyede 900 piksel.
Çarpışma bile değişirAdım büyüdükçe mermi ince bir engelin içinden “atlayarak” geçebilir. Hata bazı bilgisayarlarda görünür, bazılarında hiç çıkmaz.

Programcıların en meşhur cümlesi

Oyun çok hızlı, oynanmıyor!
😫
oyuncu · 144 Hz monitör
Tuhaf… Bende gayet normal.
🧑‍💻
geliştirici · 60 Hz dizüstü
“Benim bilgisayarımda çalışıyordu.”
🤷
çözüm değil

Fizik tabanlı ya da ağ üzerinden eşlenen oyunlarda bu fark kabul edilemez.

Hareketi frame sayısına bağlamayalım. Peki neye bağlayalım?

Bir araba “saatte 60 km” gider; “motor devri başına 2 metre” demeyiz. Hızın doğal birimi ne?

Geçen süreye: deltaTime

deltaTimeBir önceki draw() çağrısından bu yana geçen süre, milisaniye cinsinden. p5.js otomatik günceller; bizim atamamız gerekmez.
FPSdeltaTime
60≈ 16.7 ms
30≈ 33.3 ms
10≈ 100 ms

Frame’ler seyrekleşince her frame’in “süresi” uzar. Bu süreyi biliyorsak, o frame’de ne kadar yol alınacağını hesaplayabiliriz.

Yol = hız × süre

HIZSaniyede kaç piksel?
120 piksel / saniye
× süreBu frame kaç saniye sürdü?
deltaTime / 1000
= yolBu frame’de kaç piksel?
≈ 2 piksel
Kritik birimdeltaTime milisaniyedir, saniye değil. 1 saniye = 1000 ms olduğu için önce 1000’e bölünür.

Sayılarla izleyelim

İfadeÖrnek değerAnlamı
HIZ120Saniyede 120 piksel
deltaTime≈ 16.7 (ms)Son frame’in süresi; henüz saniye değil
deltaTime / 1000≈ 0.0167 (s)Aynı süre, saniye cinsinden
HIZ * deltaTime / 1000≈ 2 pikselBu frame’deki kayma

Aynı top, bu kez deltaTime ile

“Düzenle” ile frameRate(60) değerini 30, sonra 10 yapın. Top takılarak ilerler ama aynı sürede aynı yolu alır.

İki yöntem yan yana

Yöntem60 FPS (dt ≈ 16.7 ms)30 FPS (dt ≈ 33.3 ms)Saniyede toplam
topX + 3+3 px / frame+3 px / frame180 px ve 90 px
topX + 120 * dt+2 px / frame+4 px / frame≈ 120 px, ikisinde de
İşin sırrıFrame süresi kısalınca frame başına eklenen piksel azalır ama frame sayısı artar. Süre uzayınca tersi olur. Saniyedeki toplam aynı kalır.

/ 1000 yazmayı unutursak ne olur?

deltaTime yaklaşık 16.7 iken bir frame’de kaç piksel eklenir?

Top ekrandan fırlar

🚀Saniyede 100 piksel istemiştim100 × 16.7 ≈ 1670 piksel. Her frame’de.
En sık tuzakYanlış birimle çarpmak. Top saniyede 100 değil, on binlerce piksel yol alır.

Birim özeti: HIZ piksel/saniye · deltaTime / 1000 saniye · çarpım piksel.

Oyun açıkken başka bir sekmeye geçtiniz. Beş saniye sonra döndünüz.

Sekme arka plandayken draw duraklar. Döndüğünüz ilk frame’de deltaTime kaç olur? Top ne yapar?

deltaTime çok büyüyebilir

İki frame arasındaki süre birkaç saniyeye çıkar. Top tek frame’de yüzlerce piksel atlar; bir duvarın içinden bile geçebilir.

Tek frame’de en fazla 50 ms sayılır.

OyunlardaÇoğu oyun bu sınırı koyar. Yoksa oyunu duraklatıp dönen oyuncu, karakterini haritanın dışında bulabilir.
Bu dersteki örneklerdeDoğrudan deltaTime yeterli. Sekmeden dönünce ani bir sıçrama görürseniz bu beklenen davranıştır.

Hareketli top: yatay kayma + dikey salınım

  1. Top sürekli sağa gider; tuvalden çıkınca soldan yeniden girer.
  2. Dikey konum sinüs eğrisiyle salınır.
  3. Ekranda anlık FPS ve deltaTime gösterilir.
zaman değişkeniHer frame dtSaniye kadar artan, birikimli bir saat. Salınımın fazı bu saate bağlanacak.

Hareketli top: draw

Neden frameCount değil de zaman?

sin(frameCount * 0.05)Faz frame sayısına bağlı. 30 FPS’te salınım yarı hızda olur; az önceki tutarsızlık dikey eksende geri gelir.
sin(zaman * SALINIM_HIZI)zaman geçen gerçek süredir. Salınımın hızı da FPS’ten bağımsız olur; tıpkı yatay hareket gibi.
Deneysetup içinde frameRate(30) deneyin. Topun yatay hızı gözle aynı kalmalı; yalnızca akıcılık değişir. Sonra topX = topX + 5 satırını geçici olarak geri getirip farkı gözleyin.

İki toplu karşılaştırma

  1. topA frame başına sabit gitsin: topAX = topAX + 4.
  2. topB zamana bağlı gitsin: topBX = topBX + HIZ * deltaTime / 1000 (örneğin HIZ = 240).
  3. İkisi de tuvalden çıkınca soldan yeniden girsin; farklı renklerde olsunlar.
  4. Ekranda frameRate() ve “A: frame”, “B: deltaTime” etiketlerini gösterin.
  5. frameRate(60) ve frameRate(30)’u sırayla deneyin. Hangisinin temposu değişiyor? Bir iki cümleyle not edin.
  6. Bonus: guncelle ve ciz işlerini ayrı fonksiyonlara bölün.

Yapay zekâyla: siz yazın, o ölçsün

  1. Önce iki toplu sketch’i kendiniz yazıp çalıştırın. Yapay zekâya oyunun tamamını yazdırmayın.
  2. Sketch’inizi yapıştırıp ölçüm isteyin: “Mekaniği bozma. Her iki top için son 1 saniyede kat edilen yatay yolu ölçüp ekranda göster. 30 ve 60 FPS için beklenen farkı kısa bir tabloyla yaz. Class kullanma.”
  3. Kontrol edin: A’nın saniyedeki yolu FPS ile değişiyor mu, B’ninki sabit mi? Yapay zekâ deltaTime’ı iki kez mi böldü, 1000’i mi unuttu?
  4. İsteğe bağlı cilâ: tuşla 30 / 60 geçişi, min(deltaTime, 50) tavanı, hafif iz. Sonra “neleri değiştirdin, madde madde açıkla” deyin.

Yapay zekâyla: sınırlı deltaTime

  1. Sekmeden dönünce deltaTime’ın çok büyüdüğü senaryoyu kendi cümlelerinizle yazın.
  2. Yapay zekâdan min(deltaTime, 50) benzeri bir sınırlama (clamp) iskeleti isteyin.
  3. Kendi top örneğinizde sınırlı ve sınırsız sürümü deneyin; başka sekmeye geçip dönerek farkı gözleyin.

Kod zamanı

  1. Topun hızını saniyede 300 piksel yapın. Tuvali kaç saniyede geçmeli? Ölçün.
  2. Geri sayım: 10 saniyeden geriye sayan bir sayaç yazın. frameCount kullanmayın; deltaTime ile biriktirin.
  3. Hızlanan top: hız her saniye 50 piksel/saniye artsın.
  4. Zorlu: top iki kenar arasında sekerek gidip gelsin; hareket deltaTime ile olsun, sınır min(deltaTime, 50) ile korunsun.

Dört soru ve bir köprü

1VeriDurumu hangi değişkenler tutuyor?
2GüncellemeHer frame’de ne değişiyor?
3ÇizimGörünenler nereden geliyor?
4KuralHangi koşul neyi tetikliyor?

Köprü cümlesi: “Şimdi X biliyorum; bundan sonra Y için buna ihtiyacım var.” Bugünkü konu için doldurun.

HIZ = 200 piksel/saniye, bu frame 20 ms sürdü. Top kaç piksel ilerler?

  1. 200
  2. 20
  3. 4
  4. 4000

20 ms = 0.02 saniye. 200 × 0.02 = 4 piksel.

Kod x += 3. Oyuncunun monitörü 144 Hz ve oyun 144 FPS’te çalışıyor. Saniyede kaç piksel?

  1. 180
  2. 144
  3. 432
  4. 3

144 × 3 = 432. Siz 60 FPS’te 180 piksel/saniye için tasarlamıştınız; oyun bu oyuncuda 2,4 kat hızlı.

Hangisi her bilgisayarda saniyede 150 piksel ilerletir?

  1. x = x + 150;
  2. x = x + 150 * deltaTime;
  3. x = x + 150 * deltaTime / 1000;
  4. x = x + 150 / deltaTime;

Hız (piksel/saniye) × süre (saniye) = yol (piksel). deltaTime milisaniye olduğu için 1000’e bölünür.

Merak edenler için kaynaklar

Bugün ne öğrendik?

  • x += n FPS’e bağımlıdır: frame sayısı değişince hız değişir.
  • deltaTime: son frame’den bu yana geçen süre, milisaniye.
  • Hız piksel/saniye olarak yazılır: x += HIZ * deltaTime / 1000.
  • / 1000 unutulursa top ekrandan fırlar.
  • Sekmeden dönünce deltaTime çok büyür; min(deltaTime, 50) ile sınırlanabilir.
  • Salınım gibi zamana bağlı her şey için frameCount yerine biriken zaman.

Sıradaki ders

Tek top yetmez: yüz top lazım

Diziler: birçok değeri tek bir adla tutmak.