holodepth

HTML5 Canvas · Oyun mantığı ve çarpışma

Hız ve hareket: vektör entegrasyonu ve zaman adımı

Canvas 2D oyun döngüsünde nesnenin durumu çoğu zaman konum ( x, y ) ve hız ( vx, vy ) ile temsil edilir; kare başına bu iki sayı çiftini güncellemek «hareket» demektir. Basit yaklaşım: önce ivmeyi hıza ekleyin, sonra hızı konuma — semi-implicit Euler yeterli doğruluk / maliyet dengesi sunar. Bu sayfa integrasyon sırasını, delta time güvenliğini ve sürtünme gibi yaygın süzülmeleri sabitler; çarpışma geometrisi AABB çarpışması ve Daire çarpışması komşu başlıklarda — burada yalnızca konum güncellemesi ile çarpışma çözümünün sırası köprülenir.

Zaman politikası Delta time ve kare yaşam döngüsü Kare yönetimi ile uyumlu düşünülmelidir; oyun kuralları ve durum geçişleri Oyun durumu mantığı sayfasına bağlanır — Temel fizik ise kuvvet–ivme–kütle katmanını tamamlar.

Özet: birikim adımları

Adım Ne güncellenir? Tipik girdi
İvme → hız vx, vy Yerçekimi, itiş, kullanıcı girdisi
Hız → konum x, y Aynı dt ile ölçeklenmiş hız
Süzülme Hız ( sürtünme / hava ) Katsayı veya hedef sürtünmesiz hız
Çarpışma düzeltmesi Konum ( ve gerekiyorsa hız ) Geometri katmanından sonra

Konum ve hız: iki bileşenli durum

Düzlemde serbest hareket için dört skaler ( x, y, vx, vy ) çoğu prototipi taşır. Hızın birimi «dünya birimi / saniye» olarak sabitlenmelidir; piksel ile dünya birimi aynıysa doğrudan tuval pikseline eşlersiniz — kamera ölçeği varsa çizim katmanında ölçeklersiniz, entegrasyon dünyada kalır.

Yön anahtarı kodda tutulduğunda ( ok tuşları, analog eksen ) önce giriş vektörünü oluşturup sonra normalize edip hız hedefine çarpmak yaygındır; böylece çapraz gidiş fazla hızlı olmaz. Bu sayfa normalize ve giriş haritasını ürün katmanında bırakır; yalnızca «giriş → ivme veya hedef hız» üretildiğinde integrasyonun tutarlı kalması gerektiğini vurgular.

Üstten bakış araçlarında ileri hız ile dönüş açısı ( yaw ) ayrı tutulur; pozisyon güncellemesi vx = speed * cos(θ), vy = speed * sin(θ) biçiminde de kurulabilir — bu, hız vektörünü doğrudan saklamak yerine skaler hız + yön modelidir. Hangi temsil seçilirse seçilsin, dt ile ölçekleme kuralı değişmez.

Delta time: ölçek, üst sınır ve sabit adım

Gerçek zamanlı oyunda kare süresi dalgalanır; x += vx yazmak hızı kare hızına bağlar ve cihazlar arası oynanışı bozar. Doğru biçim x += vx * dt ile hızı saniye bazına bağlamaktır — Delta time ilkesinin özüdür.

Sekme arka planda beklerken tek karede devasa dt gelmesi «ölüm sarmalı» ( spiral of death ) riskini doğurur — bu yüzden dt için üst sınır ( clamp ) yaygın koruma katmanıdır. Sabit fizik adımı ( birikimli zaman ile birkaç alt adım ) daha deterministik simülasyon verir; prototipte basit clamp, üründe sabit adım çoğu ekibin yol haritasıdır.

Birikimli sabit adım: gerçek dt bir «zaman birikimcisine» eklenir; birikim sabit fizik adımına ulaştıkça bir veya daha fazla iç adım çalıştırılır. Bu, simülasyonu kare hızından bir miktar ayırır; görüntüleme ile simülasyon ayrımı için Update vs render düşüncesiyle birlikte okunmalıdır.

/** b: { x, y, vx, vy, ax?, ay? }. Önce ivme, sonra konum — semi-implicit Euler. */
function clampDt(dt, maxStep = 0.05) {
  return Math.min(Math.max(dt, 0), maxStep);
}

function integrateBody(b, dtRaw) {
  const dt = clampDt(dtRaw);
  const ax = b.ax ?? 0;
  const ay = b.ay ?? 0;
  b.vx += ax * dt;
  b.vy += ay * dt;
  b.x += b.vx * dt;
  b.y += b.vy * dt;
}

İvme ve kuvvet köprüsü: dünya birimi tutumu

Kuvvet tabanlı modelde F = ma ile ivme üretilir; oyun döngüsünde çoğu zaman doğrudan ivme ( ax, ay ) atanır — özellikle sabit kütle varsayımında. Yerçekimi Canvas’ta genelde pozitif ay ( y aşağı ekseni ) ile eklenir; işaret kararını tek dokümanda sabitleyin.

İvmeyi her kare sıfırlayıp toplayan «birikim» kalıbı ( önce kuvvetleri ekle, sonra entegre et ) öngörülebilirdir; bazı projelerde sürekli ivme ( yerçekimi ) kalır, geçici ivmeler ( zıplama ) tek karelik eklenir. Detaylı kuvvet modeli Temel fizik sayfasına bırakılır — burada entegrasyon öncesi ax/ay’nin tanımlı ve birim olarak saniye ölçekli olduğu şarttır.

Zıplama gibi anlık tepkilerde tek karelik büyük dikey hız vermek yaygındır; yerçekimi ise her kare sabit ay ile hızı sürekli değiştirir — ikisini aynı blokta karıştırmamak için kare başında ax/ay’yi sıfırlayıp kuvvet kaynaklarından doldurmak okunabilirlik sağlar.

Sürtünme ve üst hız: süzülme ve clamp

Basit sürtünme, hızı her karede bir katsayı ile çarpmaktır: v *= pow(k, dt) üstel süzülmeye yaklaşır; küçük dt için v *= k kaba ama yaygındır. Hedef: oyuncunun durması beklenen zeminde belirli süre içinde durmak — katsayıyı deneyerek ayarlarsınız.

Maksimum hız ( speed clamp ) kaçışı önler; normalize edilmiş yön ile vx²+vy² ≤ vMax² ( kare hız karşılaştırması ) kullanmak kök maliyetinden kaçınır. Sürtünme ve clamp’ı entegrasyon döngüsünde sabit sırada uygulayın ( örn. ivmeden sonra sürtünme, en sonda hız tavanı ).

Havadayken zeminkinden daha zayıf yatay sürtünme ( air control ) çoğu platformcunun hissinin parçasıdır; bu, aynı süzülme fonksiyonuna farklı katsayı geçmek veya «yerde mi?» bayrağına göre dal dal çalıştırmak kadar basit olabilir — matematik yine dt ile ölçeklenmelidir.

/** factor: 0..1 arası kaba sürtünme (dt küçükse). vMax: üst hız. */
function dampAndClampSpeed(b, factor, vMax) {
  b.vx *= factor;
  b.vy *= factor;
  const s2 = b.vx * b.vx + b.vy * b.vy;
  const m2 = vMax * vMax;
  if (s2 <= m2 || s2 === 0) return;
  const s = Math.sqrt(s2);
  const k = vMax / s;
  b.vx *= k;
  b.vy *= k;
}

Tuval ekseni ve kamera: dünya uzayı sabiti

Canvas’ta y ekseni aşağı doğru büyür; matematik dersindeki «y yukarı» alışkanlığı ile çelişir. Yerçekimi ve zıplama işaretlerini buna göre seçmezseniz nesne «yukarı düşer». Kamera kaydırması ( scroll ) çizim matrisinde kalır; fizik durumu dünya koordinatında güncellenir — bu ayrım Event koordinatları · kaydırma ile uyumludur.

Ağdan veya düzenleyiciden gelen ünite farklıysa ( örn. 1 karo = 32 px ) entegrasyon önce mantık biriminde yapılır; çizim öncesi tek ölçek çarpanı uygulanır — yarı yolda karışık birimler birikmeye başladığında hız «anlamsız» büyür.

Sabit zaman adımında bile çizim interpolasyonu ( önceki ve şimdiki konum arasında ) ile kareler arası yumuşaklık sağlanabilir; bu sayfa entegrasyon çekirdeğini verir, ara değer görüntüleme ürün katmanıdır.

Çarpışma ile sıra: önce hareket, sonra geometri

Tipik kare: giriş okuma → ivme/hız güncelle → konum entegrasyonu → çarpışma düzeltmesi ( konum ayırma ) → tepki ( hız yansıması veya sıfırlama ). Konumu çarpışmadan önce ilerletmek tünel riskini azaltmak için gereklidir; ardından iç içe kalan gövdeyi geometri katmanı iter ( AABB çözünürlük, Daire ayırma ).

Tetik ve hasar mantığı bazen çarpışma olayı anında çalışır; yine de fizik konumu ile görsel senkron için tek kaynak gerçek önerilir — Oyun durumu mantığı ile olay kuyruğu düşünün.

Hareket sonrası tuval dışına taşma ( sınır dünyası ) için konumu clamp’lemek ile hızı sıfırlamak farklı hissiyat verir — duvara sürtünerek durma genelde hız bileşenini yüzeye göre iptal etmeyi gerektirir; bu, çarpışma yanıtının parçasıdır ve geometri sayfalarıyla birlikte tasarlanır.

Anti-kalıplar: kare tabanlı hız ve karışık dt

x += vx: Hız kareye bağlı kalır; farklı FPS’te oyun değişir. Çözüm: * dt.

Büyük dt korumasız: Tek sıçramada haritayı geçmek veya duvar içine gömülmek. Çözüm: clamp veya sabit alt adım.

Çarpışma öncesi hız impulsu: İç içe gövde ile enerji birikir. Çözüm: önce ayırma ( sıra bölümü ).

Y ekseni işareti: Yerçekimi ve zıplama ters çevrilmiş hissiyat. Çözüm: tek dokümanda eksen sözleşmesi.

Bu sayfanın sınırı

Runge–Kutta, konum–Verlet ve tam fizik motoru entegrasyonu burada derinleştirilmez. Amaç: Canvas tabanlı prototip ve hafif oyunlarda güvenilir ve ölçülebilir hareket çekirdeği kurmaktır.

  • Hız ve konum birimleri saniye ile ölçekli mi?
  • dt üst sınırı veya sabit adım politikası var mı?
  • Sürtünme ve hız tavanı sabit sırada mı uygulanıyor?
  • Çarpışma düzeltmesi entegrasyondan sonra mı geliyor?
  • Yerçekimi işareti tuval ekseniyle uyumlu mu?