2015-07-04 50 views
5

Ben html tuval bir oyun kurmayı gitmek yaşıyorum. Bu bir Air Hockey oyunu ve bende oldukça uzağım var. Oyunda üç daire, vurulacak disk ve iki denetleyici (diske/daireye vurmak için kullanılır) vardır.Tuval daire çarpışması, çevrelerin bir kez çarpışması gereken noktalarda nasıl çalışılır?

Diskin duvarlardan geri tepmesini ve diskin bir denetleyiciyle ne zaman çarpıştığını algılamak için bir işlevim var. Çatıştığım şey, iki dairenin çarpışması, kontrolörün hala durması ve diskin doğru yönde hareket etmesi gerektiğidir. Bir sürü makale okudum ama yine de doğru anlayamıyorum.

İşte bir Codepen, şu ana kadar kaydettiğim ilerlemeyi gösteriyor. Paketin kontrolörden geri tepmesini ancak doğru yönde olmadığını görebiliyorsunuz. Paketin kontrolörün arkasından gelip gelmediğini de göreceksiniz. http://codepen.io/allanpope/pen/a01ddb29cbdecef58197c2e829993284?editors=001

Sanırım ne olduğum elastik çarpışmadır ama nasıl çalışacağı konusunda emin değilim. Bu makaleyi buldum ancak çalışmayı başaramadım.

http://gamedevelopment.tutsplus.com/tutorials/when-worlds-collide-simulating-circle-circle-collisions--gamedev-769

İşte benim çarpışma algılama fonksiyonudur. Kendini diske atıfta bulunur ve denetleyici [i] diskin vurduğu denetleyicidir.

this.discCollision = function() { 

     for (var i = 0; i < controllers.length; i++) { 
       // Minus the x pos of one disc from the x pos of the other disc 
       var distanceX = self.x - controllers[i].x, 
         // Minus the y pos of one disc from the y pos of the other disc 
         distanceY = self.y - controllers[i].y, 
         // Multiply each of the distances by itself 
         // Squareroot that number, which gives you the distance between the two disc's 
         distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY), 
         // Added the two disc radius together 
         addedRadius = self.radius + controllers[i].radius; 


       // Check to see if the distance between the two circles is smaller than the added radius 
       // If it is then we know the circles are overlapping 
       if (distance <= addedRadius) { 

        var newVelocityX = (self.velocityX * (self.mass - controllers[i].mass) + (2 * controllers[i].mass * controllers[i].velocityX))/(self.mass + controllers[i].mass); 
        var newVelocityY = (self.velocityY * (self.mass - controllers[i].mass) + (2 * controllers[i].mass * controllers[i].velocityX))/(self.mass + controllers[i].mass); 

        self.velocityX = newVelocityX; 
        self.velocityY = newVelocityY; 

        self.x = self.x + newVelocityX; 
        self.y = self.y + newVelocityY; 

       } 
      } 

    } 

bir daire çarpışma demo & onların çarpışma formülü uygulamaya çalışmıştır yapıbozuma

güncellendi. Bu aşağıdadır, & no'lu diski/diske vurmak için çalışır, ancak bir sebepten ötürü arkaya ya da yukarı vurmayacaktır.

this.discCollision = function() { 

      for (var i = 0; i < controllers.length; i++) { 
        // Minus the x pos of one disc from the x pos of the other disc 
        var distanceX = self.x - controllers[i].x, 
          // Minus the y pos of one disc from the y pos of the other disc 
          distanceY = self.y - controllers[i].y, 
          // Multiply each of the distances by itself 
          // Squareroot that number, which gives you the distance between the two disc's 
          distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY), 
          // Added the two disc radius together 
          addedRadius = self.radius + controllers[i].radius; 

        // Check to see if the distance between the two circles is smaller than the added radius 
        // If it is then we know the circles are overlapping         
        if (distance < addedRadius) { 

          var normalX = distanceX/distance, 
           normalY = distanceY/distance, 
           midpointX = (controllers[i].x + self.x)/2, 
           midpointY = (controllers[i].y + self.y)/2, 
           delta = ((controllers[i].velocityX - self.velocityX) * normalX) + ((controllers[i].velocityY - self.velocityY) * normalY), 
           deltaX = delta*normalX, 
           deltaY = delta*normalY; 

          // Rebound puck 
          self.x = midpointX + normalX * self.radius; 
          self.y = midpointY + normalY * self.radius; 
          self.velocityX += deltaX; 
          self.velocityY += deltaY; 

          // Accelerate once hit 
          self.accelerationX = 3; 
          self.accelerationY = 3; 

        } 
      } 

    } 
+1

Yeni yön iki vektörün toplamı olacaktır. v1 = vx, top vy. v2 = v1'e eşit büyüklükte 2. topun kenarına dik. –

+0

denetleyici durağan olduğundan, onun kütlesini devasa olarak kabul edebilir ya da hiçbir momentumun emilmediğini ya da yalnızca yeniden yönlendirildiğini varsayan farklı bir formül kullanabilirsiniz. –

+0

Bu siteyi https: //phet.colorado görselleştirmek için deneyin.edu/sims/vector-addition/vector-addition_en.html –

cevap

0

Kodumdaki ana sorun, kullanıcı denetleyicinin fareye takılı olmasıydı. Bir çarpışma meydana geldiğinde, işlev sürekli olarak çalışacak, çünkü fare konumu nedeniyle hala dokunaklı olan daireler. Kodumu değiştirdim, böylece denetleyici kullanıcı klavyesi tarafından kontrol ediliyor.

Ayrıca reddit & numaralı telefondan yardım talebinde bulundum. Bağlantılı bazı iyi kaynaklar. (http://www.reddit.com/r/javascript/comments/3cjivi/having_a_go_at_building_an_air_hockey_game_stuck/)

0

Ben matematik problemleri bu tür büyük değilim, ama sen sinüs ve kosinüs açıları etrafında vektörleri döndürmek gerekiyor gibi görünüyor. Size çalışan bir örnek ve onu yönlendiren kaynak koduna işaret edeceğim. Bu örneği ben almadım.

Son zamanlarda bu sorunun yalnızca daire çarpışma algılamayı çözdüm, ancak karşılaştığım bir çözüm yeni vektör yönergeleri oluşturmak için kod içeriyor. Ira Greenburg orijinal kaynağını processing.org numaralı telefona ev sahipliği yapıyor. Ira ayrıca Keith Peter's Çözümünü Foundation Actionscript Animation'da da ileri sürüyor: Nesneleri Hareket Ettirmek!

Ira'nın kodunu İşleme'nin Javascript kipine kopyaladıktan sonra Github Pages numaralı telefona kopyaladım, böylece denemeden önce onu görebilirsiniz.

+0

Teşekkürler. Bu Matematik problemlerinde de pek iyi değilim, ilk defa böyle bir şey yapmayı denedim. Çözümünüzü kontrol ettim ama harici bir kütüphane kullanmaktan uzak durmayı tercih ediyorum. – Allanp

İlgili konular