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.
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;
}
}
}
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. –
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. –
prova questo sito per visualizzarlo https: //phet.colorado.edu/sims/vector-addition/vector-addition_en.html –