holodepth

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

Temel fizik: kuvvet, kütle ve Canvas dünyasında ivme

Bu sayfa, 2D Canvas oyun döngüsünde «fizik hissini» üreten kuvvet → ivme → entegrasyon zincirinin ilk halkasını sabitler: Newton’un ikinci yasası (F = ma ) pratikte çoğu zaman kuvvetleri biriktirip kütleyle bölmek olarak yazılır; konum ve hızın zamanla nasıl değişeceği ise Hız ve hareket sayfasındaki Euler / dt katmanına devredilir. Amaç: motor kütüphanesi kurmadan, tek dosyada okunabilir ve ölçülebilir bir model — çarpışma geometrisi ve ayırma işleri AABB çarpışması ile Daire çarpışması başlıklarında kalır.

Zaman ölçeği ve kare politikası için Delta time, simülasyon ile çizimi ayırmak için Update vs render ile birlikte düşünün; giriş tarafında eksen ve kaydırma ayrımı Event koordinatları ile uyumludur.

Özet: fizik katmanı sırası

Aşama Durum / ara değer Bu sayfada
Kuvvet birikimi fx, fy Sıfırlama ve toplama kalıbı
İvme ax, ay F/m, sıfır kütle koruması
Özel ivmeler Yerçekimi, sürüklenme Sabit g, doğrusal / üstel süzülme
Dürtme Anlık vx, vy Zıplama ve olay tabanlı sıçrama
Entegrasyon Hız ve konum Hız ve hareket

Kuvvet ve ivme: birikim kalıbı ve Newton köprüsü

Sürekli zaman için F = ma ilişkisi ivmeyi a = F/m olarak verir; ayrık oyunda «şu karede net kuvvet nedir?» sorusunu yanıtlamak üzere kütle üzerinden bölersiniz. Çoğu prototipte kuvvet bileşenleri dünya biriminde ( saniye bazlı ) tanımlanır; böylece ivme üretildikten sonra aynı dt ile hız ve konuma taşınır. Kuvvetleri vektör olarak düşünmek ( fx, fy ) çarpışma tepkisinde normal yönü ile uyumludur — tek eksenli oyunlarda ikinci bileşen sıfır kalır.

Kare başında kuvvetleri sıfırlayıp kaynak kaynak eklemek ( yer çekimi, oyuncu itişi, yay, manyetik alan ) öngörülebilir bir sıradır; «bir önceki kareden kalan kuvvet» tutulmaz — sürekli etkiler her kare yeniden eklenir. Sürtünme veya hava direnci kimi zaman kuvvet ( hızın tersine küçük bir vektör ) kimi zaman doğrudan hız çarpanı ( süzülme ) olarak yazılır; ikinci yol entegrasyon sırasına göre bu sayfanın «kuvvet» katmanını atlayabilir — önemli olan aynı davranışı iki kez uygulamamak.

İsimlendirme: fizik motorlarında «impulse» ( dürtme ) ile «force» ( kuvvet ) farklıdır; dürtme doğrudan momentum değişimi verir ve kütle ile bölünmez ( bu sayfada basitçe hıza ek olarak gösterilir ), kuvvet ise ivmeye çevrilir. Karmaşık çarpışma çözümü burada açılmaz; yalnızca veri akışının nereye oturacağı işaretlenir.

/**
 * body: { fx, fy, ax, ay, mass } — kare başı reset → addForce → accelFromForces → entegrasyon (başka dosya).
 */
function resetForces(body) {
  body.fx = 0;
  body.fy = 0;
}

function addForce(body, fx, fy) {
  body.fx += fx;
  body.fy += fy;
}

/** Önceden hesaplanmış yerçekimi ivmesi g ile: F = m·g, fy pozitif = Canvas’ta aşağı */
function addGravityForce(body, ayGravity) {
  body.fy += body.mass * ayGravity;
}

function accelFromForces(body) {
  const m = body.mass;
  if (typeof m !== "number" || !Number.isFinite(m) || m <= 0) {
    body.ax = 0;
    body.ay = 0;
    return;
  }
  body.ax = body.fx / m;
  body.ay = body.fy / m;
}

Kütle ve ters kütle: kararlılık ve oyun hissiyatı

Kütle yalnızca «gerçekçilik» için değil; aynı kuvvet altında farklı ivmeler üreterek nesneleri ayırt etmek için kullanılır. Sabit kütle varsayımında her gövde için mass = 1 seçmek kodu sadeleştirir — bu durumda kuvvet doğrudan ivmeye eşlenir ve matematiksel olarak a = F yazılır; birimleri yine saniye ile ölçekli tutmak gerekir.

Performans için invMass = 1/mass saklamak yaygındır; ivme ax = fx * invMass ile çarpılır ve bölme maliyeti kareden kareden düşer. Sonsuz kütle ( duvar, zeminin sabit bloğu ) için invMass = 0 kullanımı entegrasyonu atlamayı veya tepkiyi tek taraflı yazmayı kolaylaştırır — Canvas demosunda «hareket etmeyen» nesneyi böyle işaretlemek netleşir.

Oyun tasarımında kütle ile «itiş gücü», «havada kalma süresi» ve «çarpışma sonrası geri sekme» birbirine bağlanır; rakamları fizik dersi doğruluğunda değil, tekrarlanabilir his için ayarlarsınız. Önemli olan ekibin aynı sözleşmeyi ( piksel mi, karo mu, saniye bazlı ivme mi ) paylaşmasıdır.

Yerçekimi ve sabit ivme: tuval yönü ile uyum

Yerçekimi çoğu 2D platformda sabit dikey ivme olarak modellenir; Canvas’ta y ekseni aşağı büyüdüğünden «düşme» için ivmenin işareti genelde pozitif seçilir ( aşağı ivme ). Bu kararı dokümante etmezseniz kutu fizik kodunda «yukarı çeken yerçekimi» üretirsiniz — tuval ekseni sayfasıyla aynı dilde kalın.

Kuvvet formunda yazmak ( Fy = m * g ) ile doğrudan ivme eklemek ( entegrasyon öncesi ay += g ) sabit kütlede özdeştir; farklı kütlelerde ilk yol ölçeklemeyi tek yerde toplar. Çoklu gök cisimleri veya değişken yerçekimi için g’yi alan bazlı fonksiyon yapmak yeterlidir — ağır geometri bu sayfanın kapsamı dışındadır.

«Terminal hız» ( süzülme ile tavan hız ) genelde yerçekimi ile aynı blokta değil, hız güncellemesinden sonra uygulanan bir sürtünme katmanıdır; aksi halde düşüş ve yatay koşu sürtünmesi çakışır. Su / balon gibi ortamlar için g yerine yüzdürme kuvveti hayali eklemek yeterli prototip olabilir.

Sürüklenme ve direnç: hız ile orantılı kuvvet

Doğrusal sürüklenme F = -k v biçiminde modellenir; ayrık zamanda küçük dt için hızın çarpanla çarpılmasına yaklaşır. Canvas demosunda amaç genelde «durunca durmak» ve «havada süzülmek» arasında ince ayar yapmaktır — katsayı birimleri kuvvet modeline bağlıdır; tutarsızlıkta nesne ya donar ya asılı kalır.

Üstel yaklaşım ( v *= pow(dragCoef, dt) ) veya sabit çarpan ( v *= k ) daha basit ve çoğu oyunda yeterlidir; bunları zaten hız katmanında kullanıyorsanız ikinci bir «sürüklenme kuvveti» eklemeyin. Bu sayfa kuvvet yazımını gösterir; entegrasyon sırasını projenizde tekilleştirin.

Rüzgâr için sabit fx eklemek veya oyuncuya göre ücretli bir vektör kullanmak yaygın «çevre kuvveti» örneğidir; sürekli kuvvetler yerçekimi ile aynı birikim döngüsüne girer.

/**
 * Doğrusal sürtünme kuvveti: F = -k * v (k >= 0). resetForces sonrası addForce ile çağırın.
 */
function addLinearDragForce(body, k) {
  body.fx -= k * body.vx;
  body.fy -= k * body.vy;
}

Dürtme ve olay tabanlı hız: zıplama ve tek karelik tepki

Tuşa basıldığı anda zıplama çoğu projede ya sabit dikey hız ( vy -= jumpSpeed tuval yönüne göre ) ya da kısa süreli ek ivme ile verilir. «Gerçek» dürtme J ile Δv = J/m bağlantısı kurar; sabit kütlede J doğrudan hız artışı gibi kodlanabilir — tasarım kararıdır.

Olay tabanlı dürtmelerde giriş filtresi önemlidir: tek karede iki kez zıplama ( tuş tekrarı / çift okuma ) «havada süper sıçrama» üretir; yerde mi kontrolü ( zemin bayrağı veya çarpışma olayı ) genelde oyun durumu veya geometri katmanına bağlıdır — burada yalnızca matematiksel eklemenin güvenli yapıldığı gösterilir.

Çarpışma sonrası sekme veya itiş için dürtme vektörü, geometrinin verdiği normal yön ile hizalanır; tam çözüm daire / AABB sayfalarına gönderilir. Bu sayfa dürtmeyi «ivmeden bağımsız tekil hız ekı» olarak konumlandırır.

/** Anlık hız ekı — entegrasyon öncesi veya sonra tek yerde çağırın (çift uygulamayın). */
function applyVelocityImpulse(body, ix, iy) {
  body.vx += ix;
  body.vy += iy;
}

Birimler ve ölçek: tutarlı dünya modeli

Canvas koordinatları piksel olabilir; bu durumda «1 piksel / saniye» hız ve «piksel / saniye²» ivme kullanırsınız. Karo tabanlı dünyada önce mantık biriminde ( karo ) fizik yapıp sonra çizimde ölçeklemek okunabilirliği artırır — ara değerleri karışık birimde biriktirmek debug’ı zorlaştırır.

Kuvvet birimini «Newton» olarak zorunlu tutmak şart değil; birçok oyun «keyfi kuvvet birimi» kullanır ve ivmeyi doğrudan tasarım tablosundan seçer. Önemli olan tüm kuvvet ve ivme katmanlarının aynı zaman ölçeğinde olması ve dt ile uyumlu entegrasyondur.

Sabit fizik adımı kullanıyorsanız kuvvetler de aynı iç adımın süresine göre ölçeklenmelidir; yarı-implicit Euler’da yanlış yerde çarpılmış dt enerji üretir veya boğar. Bu tema özetle hız sayfasında işlendi; burada kuvvet tarafının aynı disipline bağlı olduğu hatırlatılır.

Çarpışma köprüsü ve sıra: ivmeden sonra geometri

Tipik kare akışı: giriş → kuvvetleri oluştur → ivmeyi çıkar → hız ve konumu entegre et → çarpışma ile konumu düzelt ve gerekiyorsa hızı yansıt. Kuvvet katmanını çarpışma öncesinde tamamlamak, tünellemeden sonra «içeride kalan ivme» hayaletlerini azaltır; geometri katmanı yalnız konumu ayırmakla kalmayıp yüzey normaline göre hız bileşenini güncelleyebilir.

Yaylı bağlar, makara ve kısıtlı gövdeler ( constraints ) için basit Canvas oyunlarında sıkça özel çözümler yazılır; genel amaçlı fizik motoru kurmak bu içeriğin dışındadır. İhtiyaç halinde mevcut kütüphaneleri düşünün — öğrenme hedefi burada CPU üzerinde anlaşılır küçük model kurmaktır.

Enerji korunumu ve tam elastik çarpışma formülleri rekabetçi simülasyon için gerekebilir; arcade his için ise sabit sekme yüzdeleri ve üst hız tavanları daha sık ayarlanır. Hız tavanı ve süzülme ile birlikte düşünüldüğünde oynanış tek elle tutulur hale gelir.

Anti-kalıplar ve yaygın tuzaklar

Sıfır veya negatif kütle: F/m sonsuz veya ters yönlü ivme üretir. Örnekte kütle doğrulaması vardır; üretimde savunmacı kontrol şart.

Çift sürtünme: Hem kuvvet olarak sürtünme eklemek hem hız çarpanı uygulamak nesneyi öldürür; tek kanal seçin.

Dürtme + ivme aynı olayda: Zıplama hem vy artırıp hem büyük ay eklemek tek karede aşırı sıçrama yapar; tek kaynak kullanın.

Y ekseni işareti: Yerçekimi ve zıplama karşıt işaretlerde olmalıdır — yerçekimi bölümü.

Bu sayfanın sınırı

Çarpışma tepkisinin tam matematiği, dönmeli gövdeler ( rigid body ), yay–sönüm sistemleri ve sayısal stabilite ( solver ) burada derinleştirilmez. Odak: Canvas 2D için güvenli ve küçük bir kuvvet→ivme katmanı tanımlamak ve komşu başlıklara düzgün bağlanmaktır.

  • Kuvvetler her kare sıfırlanıp yeniden mi toplanıyor?
  • Kütle / ters kütle için tek sözleşme var mı?
  • Sürüklenme kuvveti ile hız süzülmesi çiftlenmedi mi?
  • Yerçekimi işareti tuval y ekseni ile uyumlu mu?
  • Entegrasyon sırası: ivme sonrası çarpışma geometrisi geliyor mu?