2015-07-04 25 views
5

Sto provando a costruire un gioco in tela html. È una partita di Air Hockey e sono comunque andata molto lontano. Ci sono tre cerchi nel gioco, il disco che viene colpito e i due controller (usati per colpire il disco/cerchio).Collisione di cerchi su tela, come capire dove dovrebbero spostarsi i cerchi una volta scontrati?

Ho il disco che rimbalza contro i muri e ho una funzione per rilevare quando il disco è entrato in collisione con un controller. Il problema con cui sto combattendo è quando i due cerchi si scontrano, il controller dovrebbe rimanere fermo e il disco dovrebbe allontanarsi nella direzione corretta. Ho letto un sacco di articoli ma non riesco a farlo bene.

Ecco un collegamento Codepen i miei progressi finora. Puoi vedere che il disco rimbalza dal controller ma non nella direzione corretta. Vedrai anche se il disco proviene da dietro il controller che lo attraversa. http://codepen.io/allanpope/pen/a01ddb29cbdecef58197c2e829993284?editors=001

Penso che quello che sono dopo è collisione elastica ma non sono sicuro su come risolverlo. Ho trovato questo articolo ma non sono riuscito a farlo funzionare.

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

Heres è la mia funzione di rilevamento delle collisioni. Autorappresentazione del disco e il controller [i] è il controller su cui viene eseguito il disco.

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; 

       } 
      } 

    } 

Aggiornato

decostruito un cerchio di collisione demo & cercato di implementare la loro formula di collisione. Questo è qui sotto, funziona per colpire il disco/disco in avanti & verso il basso ma non colpire la schiena all'indietro o verso l'alto per qualche motivo.

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

la nuova direzione sarà la somma di due vettori. v1 = vx, vy di palla. v2 = perpendicolare al bordo della 2a sfera con magnitudo pari a v1. –

+0

poiché il controller è fermo, è possibile assumere che la sua massa sia enorme, oppure è possibile utilizzare una formula diversa che presuppone che nessuno slancio venga assorbito o trasferito solo reindirizzato. –

+0

prova questo sito per visualizzarlo https: //phet.colorado.edu/sims/vector-addition/vector-addition_en.html –

risposta

0

Il problema principale con il mio codice era il controller utente collegato al mouse. Quando si verifica una collisione, la funzione viene eseguita costantemente perché i cerchi sono ancora in contatto a causa della posizione del mouse. Ho cambiato il mio codice in modo che il controller sia controllato dalla tastiera dell'utente.

Ho anche chiesto aiuto su reddit & ottenuto qualche aiuto con il mio codice di collisione. Alcune buone risorse se collegate. (http://www.reddit.com/r/javascript/comments/3cjivi/having_a_go_at_building_an_air_hockey_game_stuck/)

0

io non sono grande a questi tipi di problemi di matematica, ma sembra che tu abbia bisogno di ruotare i vettori intorno angoli seno e coseno. Ti indicherò un esempio funzionante e il codice sorgente che lo guida. Non ho tratto questo esempio.

Ho risolto la parte di rilevamento di collisione di questo problema recentemente, ma una soluzione che ho trovato include il codice per stabilire nuove direzioni vettoriali. Ira Greenburg ospita la sua fonte originale al processing.org. Ira cita ulteriormente la soluzione di Keith Peter in Foundation Actionscript Animation: Making Things Move!

Ho copiato il codice di Ira nella modalità Javascript di Processing, quindi lo ho spostato su Github Pages in modo da poterlo vedere prima di provarlo.

+0

Grazie. Nemmeno io sono bravo in questi problemi di matematica, la prima volta che ho provato a fare qualcosa del genere. Ho controllato la tua soluzione, ma preferirei stare lontano dall'usare una libreria esterna. – Allanp