2015-06-23 30 views
9

Şu an 2-3 hafta boyunca çalışıyorum ve hala uygun bir çarpışma algılamasına sahip olamıyorum. Dikdörtgenler kullanarak bir labirent oluşturdum. Nesnemin herhangi bir duvarla çarpışması ve herhangi bir yere taşınabilmesi (veya bir duvarı aşağı kaydırması) durumunda durmak için (Dikdörtgen içinde olan) nesneyi durdurmak istiyorum. Şu anda ben SO bulduğum bir çakışma yöntemi kullanıyorumDikdörtgenler arasındaki çarpışma algılaması (çakışma yok) - libgdx

shapeRenderer.rect(0.9f, 12, 1.15f, 0, Color.RED, Color.RED, Color.RED, Color.RED); //NORTH 
shapeRenderer.rect(1, 12, 0, -1.05f, Color.RED, Color.RED, Color.RED, Color.RED); // WEST 
shapeRenderer.rect(2, 12, 0, -1.05f, Color.RED, Color.RED, Color.RED, Color.RED); // EAST 
shapeRenderer.rect(0.9f, 11, 1.15f, 0, Color.RED, Color.RED, Color.RED, Color.RED); // SOUTH 

: My duvarlar (dikdörtgenler) Aşağıdaki gibi olumsuz koordinatları var.

private boolean overlaps (Rectangle collision, Rectangle wall) { 
    return Math.min(collision.x, collision.x + collision.width) 
     < Math.max(wall.x, wall.x + wall.width) 
    && Math.max(collision.x, collision.x + collision.width) 
     > Math.min(wall.x, wall.x + wall.width) 
    && Math.min(collision.y, collision.y + collision.height) 
     < Math.max(wall.y, wall.y + wall.height) 
    && Math.max(collision.y, collision.y + collision.height) 
     > Math.min(wall.y, wall.y + wall.height); 
} 

Ben nesne tarafından yapılan tüm pozisyon hamle kaydeder bir işlevi vardır: İşte benim CollisionManager sınıfımda bir yöntem. Bir çarpışma meydana geldiğinde (örnek aşağıdadır) (çarpışma meydana geldiğinde son hamlesini olduğundan) Böylece, nesne son hamlesini önce önceki hamlesine geri yükler:

private void overlapsTop(Entity object, Rectangle wall){ 

    Rectangle r = new Rectangle(); 
    if(spritePositions.size() != 0){ 
     r = spritePositions.get(spritePositions.size()-1); 
    } 
    object.update(r.x, r.y, r.width, r.height); 
    object.getObject().setBounds(r.x, r.y, r.width, r.height); 
    spritePositions.clear(); 
} 

Ek bilgi: Ben nesneyi hareket ediyorum Böyle:

public void moveRight(){ 
    position.x += 1f; 
    update(); 
} 

public void update(){ 

     boundingRectangle.set(position.x, position.y, object.getWidth(), object.getHeight()); 
} 

Takılıyorum, çakışma işlevim (SO içinde bulduğum). Çoğu durumda çalışır; Yine de, örneğin, nesne sağdaki bir duvarın yakınında hareket ederse ve ona dokunursa, işlev doğru döner ve her şey gerçekleşir. Ama diyelim ki, duvar boyunca kayıyor ve doğrudan aşağıya doğru hareket edersem ve duvar yok ise, nesne bir noktada durur çünkü nesnenin alt kısmı ile bir duvarın tepesi (hiç yok) arasında bir çarpışma algılar. nesnenin sağı ile bir duvarın solu arasındaki çarpışma.

Bunun için başka bir çözüm bulmaya çalışıyorum. Sadece nesnemin herhangi bir duvarda durmasını ve yakın bir duvarın olmadığı bir çarpışma olabileceğinden şüphelenmeden hareket edebilmeyi (ya da bir duvarın aşağı doğru kaymasını) istiyorum. Bir çözüme çok yakın olduğumu hissediyorum, ama biraz fazladan yardıma ihtiyacım var.

Ben MoveRight fonksiyonu ve güncelleme fonksiyonunu güncelledik

GÜNCELLEME. @Adrian Shum ve @Matthew Mark Miller Her şeyi şimdi bir tam sayı ile yaptım (0.01f yerine, 1f kullanıyorum).

Böylece taşımak için kullanmak kod aşağıdaki nesne şu şekildedir:

Benim collisionManager sınıfta
if(Gdx.input.isKeyPressed(Keys.RIGHT)){ 

       if(collisionManager.canSpriteNotMoveRight(object)){ 
        object.stopGoingRight(); 
       }else{ 
        object.moveRight(); 
       } 
      } 

, fonksiyon stopGoingRight şudur: Bugüne kadar

public void stopGoingRight(){ 
    position.x -= 1f; 
    update(); 
} 

, çok iyi. Nesne duvara çarptığında, nesne durur ve geri döner. Bu iyi. Ama elimden gelenin en iyisini açıklamaya çalışacağım başka bir problemim var (rahatsız edici olan). Örneğin, nesneyi bir duvara taşımaya devam edersem, nesne o duvardan birçok kez geri dönecektir; Yukarı tuşuna basmayı kesersem, nesne bazen duvarın içinde kalır. Böylece, aşağı tuşa bastığımda, aşağı inmek yerine (ya da sol tuşa basmak yerine, sola gitmek yerine sağa gidecektir), örtüşen fonksiyonun çalıştırılması (her iki nesne ve duvardan)) kesişir.

Bunu çözmem için bir yolu var mı? Libgdx bu tür bir çarpışma tespiti ile başa çıkmak için tam olarak uygun değil gibi görünüyor, ama şu an oyunumun inşa edilmesinde derinlere inanıyorum.

+0

Denetlemekte olduğunuz dikdörtgen döndürebilir mi? Yoksa sadece kendi yönünü mi döndürüyorsun? –

+0

Evet, dönüşünü kontrol edebilirsiniz. Temel olarak, aşağı, yukarı, sağa veya sola hareket ettiğinizde, nesne buna uygun olarak dönecektir. –

+0

Ancak "Dikdörtgen" her zaman Eksen Hizalanmış olur? – Springrbua

cevap

4

sonunda iyi çözüm aşağıdaki linke tüm sayesinde tespit ettik: On overlap, player gets stuck libgdx Rectangle.

Temel olarak, nesnenin duvarla çarpışıp çarpışmadığını görmek için "sahte" bir hareket oluşturmalıyım. Bir çarpışma varsa, sadece nesneyi durdurup yeni hareketi yapmıyorum.

Herkesin yardımları için teşekkürler :) !! Bu büyük takdir!

5

Çarpışma algoritmanız çok kötü görünüyor ama doğru görünüyor (Wordy x, x + genişlik her zaman sadece x'in genişliği x = 0 olmalıdır ve tersi de max için doğrudur).

Bu, kayan nokta hassaslığı sorunu olasılığını düşündünüz mü? Örneğin, bir fp sayısına 1 eklerseniz, sonuçtan 1'i kaldırırsanız, orijinal değere geri döndüğünüz garanti edilmez. Ara sonuç bir float olarak temsil edilemeyeceğinden biraz daha fazla olabilirsiniz.

sevdiğim örnek: .1f + .2f> .3f