This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English
Kinematik çarpışma nesnelerini (kinematic collision objects) kullanırken çarpışmaları kendiniz çözmeniz ve tepki olarak nesneleri hareket ettirmeniz gerekir. Çarpışan iki nesneyi ayırmak için basit bir uygulama şöyle görünür:
function on_message(self, message_id, message, sender)
-- Handle collision
if message_id == hash("contact_point_response") then
local newpos = go.get_position() + message.normal * message.distance
go.set_position(newpos)
end
end
Bu kod, kinematik nesnenizi iç içe geçtiği diğer fizik nesnelerinden ayırır; ancak ayırma işlemi çoğu zaman gerekenin ötesine geçer ve birçok durumda titreme görürsünüz. Sorunu daha iyi anlamak için oyuncu karakterinin A ve B adlı iki nesneyle çarpıştığı aşağıdaki durumu ele alın:

Fizik motoru, çarpışmanın gerçekleştiği karede biri A nesnesi, diğeri B nesnesi için olmak üzere birden fazla "contact_point_response" iletisi gönderir. Karakteri yukarıdaki basit kodda olduğu gibi her iç içe geçmeye tepki olarak hareket ettirirseniz ayırma işlemi şöyle gerçekleşir:
Bunların sırası değişebilir, ancak her iki durumda da sonuç aynıdır: toplam ayırma, tek tek iç içe geçme vektörlerinin toplamına eşittir:

Karakteri A ve B nesnelerinden doğru şekilde ayırmak için her temas noktasının (contact point) iç içe geçme mesafesini ele almanız ve önceki ayırma işlemlerinin gerekli ayrılmayı zaten tamamen veya kısmen sağlayıp sağlamadığını kontrol etmeniz gerekir.
İlk temas noktası iletisinin A nesnesinden geldiğini ve karakteri A nesnesinin iç içe geçme vektörü kadar hareket ettirerek dışarı çıkardığınızı varsayın:

Bu durumda karakter, B nesnesinden de kısmen ayrılmış olur. B nesnesinden tamamen ayrılmak için gereken son telafi, yukarıdaki siyah okla gösterilmiştir. Telafi vektörünün uzunluğu, A nesnesinin iç içe geçme vektörünün B nesnesinin iç içe geçme vektörü üzerine izdüşümü (projection) alınarak hesaplanabilir:

l = vmath.project(A, B) * vmath.length(B)
Telafi vektörü, B vektörünün uzunluğu l kadar azaltılarak bulunabilir. Bunu herhangi bir sayıda iç içe geçme için hesaplamak üzere, uzunluğu sıfır olan bir düzeltme vektörüyle başlayıp her temas noktası için şu adımları uygulayarak gerekli düzeltmeyi bir vektörde biriktirebilirsiniz:
Tam bir uygulama şöyle görünür:
function init(self)
-- correction vector
self.correction = vmath.vector3()
end
function update(self, dt)
-- reset correction
self.correction = vmath.vector3()
end
function on_message(self, message_id, message, sender)
-- Handle collision
if message_id == hash("contact_point_response") then
-- Get the info needed to move out of collision. We might
-- get several contact points back and have to calculate
-- how to move out of all of them by accumulating a
-- correction vector for this frame:
if message.distance > 0 then
-- First, project the accumulated correction onto
-- the penetration vector
local proj = vmath.project(self.correction, message.normal * message.distance)
if proj < 1 then
-- Only care for projections that does not overshoot.
local comp = (message.distance - message.distance * proj) * message.normal
-- Apply compensation
go.set_position(go.get_position() + comp)
-- Accumulate correction done
self.correction = self.correction + comp
end
end
end
end