Çarpışma dikdörtgen yanıtı


10

Birden fazla dikdörtgenle çarpışmak için hareketli bir dikdörtgen almakta zorlanıyorum.

SFML kullanıyorum ve intersects2 dikdörtgen alır ve kavşakları döndüren adlı kullanışlı bir işlevi vardır . Hareketli dikdörtgenin çarpışmasını istediğim dikdörtgenlerle dolu bir vektörüm var. Aşağıdaki kod (p hareket ettirilebilir dikdörtgen) kullanarak bu döngü.

IsCollidingWithbir bool döndürür ancak intersectskavşakları çözmek için SFML kullanır .

while(unsigned i = 0; i!= testRects.size(); i++){
   if(p.IsCollidingWith(testRects[i]){
        p.Collide(testRects[i]);
   }
}

ve gerçek Collide()kod:

void gameObj::collide( gameObj collidingObject ){

 printf("%f %f\n", this->colliderResult.width, this->colliderResult.height);

if (this->colliderResult.width < this->colliderResult.height) {
    // collided on X
    if (this->getCollider().left < collidingObject.getCollider().left ) {
        this->move( -this->colliderResult.width , 0);
    }else {
        this->move( this->colliderResult.width, 0 );
    }

}

if(this->colliderResult.width > this->colliderResult.height){
    if (this->getCollider().top < collidingObject.getCollider().top ) {
        this->move( 0, -this->colliderResult.height);
    }else {     
        this->move( 0, this->colliderResult.height );
    }

}

ve IsCollidingWith()kod:

bool gameObj::isCollidingWith( gameObj testObject ){
if (this->getCollider().intersects( testObject.getCollider(), this->colliderResult )) {
    return true;
}else {
    return false;
}

RectSahnede sadece 1 olduğunda bu işe yarar. Ancak, birden fazla Rectolduğunda aynı anda 2 çarpışma yaparken soruna neden olur.

Bununla nasıl başa çıkılacağı hakkında bir fikrin var mı? Sorunumu göstermek için youtube'a bir video yükledim . En sağdaki konsol kavşakların genişliğini ve yüksekliğini gösterir. Konsolda aynı anda 2 çarpışmayı hesaplamaya çalıştığını görebilirsiniz, bence bu da sorunun neden olduğu yer.

Son olarak, aşağıdaki görüntü sorunumu güzel bir şekilde gösteriyor:

dikdörtgen, diğer birçok dikdörtgenle çarpışıyor


Video bağlantısı bozuk.
XiaoChuan Yu

colliderTarafından döndürülen nesneler ?? tarafından this->getCollider()güncellendi mi this->move()?
XiaoChuan Yu

Daha fazla bilgi ekleyebilir misiniz lütfen? Sorun tam olarak nedir? YouTube videosu öngörülebilir davranış gösteriyor gibi görünüyor ve sahnede yalnızca bir dikdörtgen daha var.
Wackidev

Yanıtlar:


3

Resminiz, zemin gibi düz bir yüzeyi simüle etmek için dışbükey şekiller - özellikle dikdörtgenler - kullanmaya çalışırken karşılaşılan birçok sorundan birini göstermektedir. Algoritma, zemini oluşturan şekillerin iç kenarlarına yapışan karakterlere yol açar.

Bunun için basit bir düzeltme sadece dikey çarpışmayı kontrol etmek, düzeltmek ve sonra yatay çarpışmayı tekrar kontrol etmektir. Düşmeden ve bir duvarı aşağı kaydırmaya çalışmadığınız sürece, bu durumda önce yatay çarpışmaları kontrol etmek istersiniz. Hangisini ilk kontrol edeceğinizi nereden biliyorsunuz? Bunu hızınızın hangi bileşeninin daha büyük olduğuna bağlı olarak yapabilirsiniz (yatay hareket daha büyükse, önce dikey çarpışmaları kontrol edin, aksi takdirde yatay çarpışmaları kontrol edin).

Daha basit ve daha performanslı olabilecek şey, bunun yerine dünyanız için bir kenar listesi oluşturmaktır. Yani, zemini oluşturan kutularınız için, sadece üst kenarlarının gerçekten katlanabilir olduğunu gösteren bir bayrak ayarlayın ve daha sonra diğer kenarlarla çarpışmaları yok sayın. Bunun için SFML'nin çarpışma rutinini kullanamayacaksınız, ancak dürüst olmak gerekirse kutu çarpışmaları muhtemelen bir oyunda yazacağınız en kolay kod parçasıdır. Bu teknik, dünyanız bir ızgaraya hizalanmışsa özellikle iyi çalışır. Bu teknik için mükemmel Metanet öğreticilerine (http://www.metanetsoftware.com/technique.html/) göz atarım.

Sizin gibi basit bir 2D platform oyunu oluşturmaya çalışırken diğer birçok problemle karşılaşacaksınız. Açıkçası, bunun için latel gördüğüm en iyi kaynak aşağıdakini okumalı ve sonra tekrar okumalısınız:

http://higherorderfun.com/blog/2012/05/20/the-guide-to-implementing-2d-platformers/



0

Hesaplanan 2 çarpışmanın bir sorun olduğunu düşünmüyorum, sadece performans sorunu. Çarpışmanın doğru bir şekilde işlenmesi için iki kez test edilmesi gerekebilir. Diyagramınızı kullanarak A'nın önce B'ye karşı test edilip edilmediğini düşünün, o zaman diğer kutulara da test edilmesi gerekecektir ve başka biriyle çarpışabilir.

Umarım faydalı olur mu?


0

Bu orada en erken zaman belirlemeye çalışırken gerektiğini gerçekten optimal bir yöntem değildir hareketli boyunca ilk nokta yolunu nesneleri veya , çarpışmalar meydana ve (hesaplanan zamanda veya pozisyon) bu konuma nesneleri hareket teşebbüs hareket sonrası delici pozisyonlara göre düzeltmek çok problemlidir, ancak mevcut işleminizi küçük bir değişiklikle kullanabilirsiniz. Çarpışma olup olmadığını kontrol edin.

bool collided = true;
while(collided) {
   collided = false
   while(unsigned i = 0; i!= testRects.size(); i++){
      if(p.IsCollidingWith(testRects[i]){
         collided = true
         p.Collide(testRects[i]);
      }
   }
}

Bunun Sonsuz Döngüye yol açacağı durumlar olduğunu unutmayın (kutuyu bir çarpışmadan çıkarmanın başka bir koleksiyonla sonuçlandığı ve kutuyu o çarpışmadan çıkarmanın, önceki gibi aynı çarpışma konumuna getirdiği bir durumu düşünün)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.