Domanda

Ho giocato intorno con esso per un po', ma semplicemente non riesco a capire.

Ho fatto un carro armato che spara missili, e quando i missili ha colpito le pareti, voglio loro di rimbalzare, ma voglio loro di rimbalzare a destra angolo.

Destra ora, non ho ostacoli, i missili, rimbalzano quando ottengono fuori viewportRectangle Ho fatto.

È la soluzione che sto cercando abbastanza avanzato?

C'è abbastanza semplice modo per farlo?

È stato utile?

Soluzione

Penso che un modo più semplice per farlo è quello di utilizzare la velocità di un missile invece di calcolare gli angoli.Dici di avere un missile che ha xVelocity e yVelocity a rappresentare il movimento in orizzontale e in verticale.A quelle velocità può essere positivo o negativo a rappresentare sinistra, destra, in alto o in basso.

  • Se un missile colpisce un alto o in basso confine invertire il segno del yVelocity.
  • Se un missile colpisce a sinistra o a destra confine invertire il segno del xVelocity.

Questo per evitare il movimento sull'asse opposto lo stesso.

In prestito l'immagine da ChrisF risposta, diciamo che il missile inizia alla posizione I.

Angle of Reflection

Con il xVelocity e yVelocity entrambi positivi (in grafica 2D destra e verso il basso sono di solito positivo) il missile viaggio nella direzione indicata.Cerchiamo solo di assegnare valori di

xVelocity = 3
yVelocity = 4

Quando il missile colpisce il muro in posizione C, la sua xVelocity non dovrebbe cambiare, ma la sua yVelocity dovrebbe essere invertito a -4 in modo che ripercorre la direzione verso l'alto, ma continua ad andare a destra.

Il vantaggio di questo metodo è che avete solo bisogno di tenere traccia di un missile xPosition, yPosition, xVelocity, e yVelocity.Utilizzando solo queste quattro componenti e il gioco, frequenza di aggiornamento, il missile sarà sempre ridisegnato nella posizione corretta.Una volta che si ottiene in più complicati ostacoli che non sono in angoli, rette o sono in movimento, sarà molto più facile lavorare con X e Y velocità di con angoli.

Altri suggerimenti

Si potrebbe pensare che perché le pareti sono allineati con gli assi coordinati che ha senso scrivere codice caso speciale (per una parete verticale, nega la coordinata x della velocità, per una parete orizzontale, negare la coordinata y della velocità). Tuttavia, una volta che hai il gioco funziona bene con le pareti verticali e orizzontali, probabilmente la prossima cosa che pensa è: "che dire di pareti ad angolo arbitrari?" Quindi vale la pena di pensare al caso generale dall'inizio.

Nel caso generale, si supponga che il missile ha velocità di v e colpisce un muro con superficie normale n .

missile vettore v per colpire obliquamente una parete con superficie normale n.

Split v in componenti u perpendicolare alla parete e w parallelo ad esso.

triangolo rettangolo con ipotenusa per v, u lato corto parallelo alla parete e lato lungo w parallela alla parete.

Dove:

u = ( v · n / n · n ) < strong> n
w = v - u

Qui, v · n è il dot prodotto dei vettori v e n . Vedi il link per una spiegazione di come calcolarlo. Il prodotto scalare n · n restituisce il quadrato della lunghezza del vettore normale; se si mantiene sempre le vostre normali sotto forma di vettori unitari quindi n · n = 1 e si può omettere la divisione.

Dopo il rimbalzo, la componente di moto parallelo alla parete subisca attrito f e il componente perpendicolare alla parete è affetto da elasticità, che può essere fornita sotto forma di una coefficiente di restituzione r .

Quindi, la velocità dopo la collisione è v ' = f w - r U . In a perfettamente elastico, collisione attrito, v ' = w - u ; cioè, il moto viene riflessa sulla normale al punto di collisione, come nel diagramma indicato nella risposta di Bill.

Questo approccio funziona lo stesso in tre dimensioni troppo.

(Ovviamente questa è una nozione molto semplificata di rimbalzo,.. Non tiene conto del momento angolare o deformazione Ma per molti tipi di videogiochi questo tipo di semplificazione è perfettamente adeguata)

Per particelle perfette (e luce) l'angolo di riflessione è uguale all'angolo di incidenza, come illustrato da questo diagramma (da commons.wikimedia.org).

Angolo di riflessione

Fate una ricerca per "angolo di riflessione" (senza le virgolette) in Google.

E 'un po' più complicato quando si prende in considerazione l'elasticità e materiali dell'oggetto e gli ostacoli;)

Ho avuto questo problema, l'unico modo che ho trovato è stato che separa gli assi di collisione!

Da provare:

x += velocity * Math.cos(angle * Math.PI /180);
y += velocity * Math.sin(angle * Math.PI /180);

if (x < 0 || x > canvas.width) {
     angle = 180 - angle;   
}
else if (y < 0 ||y > canvas.height) {
     angle = 360 - angle; 
}

Spero che questo ti aiuta!

Per inciso alla specifica domanda di fisica si sta chiedendo, consiglio il libro "A partire matematica e fisica per il gioco programmatori" di Wendy Stahler. Ho trovato molto utile per il mio gioco / progetti di programmazione di fisica.

Il codice che accompagna il libro è C ++, ma se si sa C #, sarebbe piuttosto facile fare la conversione.

Avere una buona!

Non per nulla complesso - pseudo-codice:

angleObjectHitWall = a;
bounceAngle = 180-a;

Naturalmente questo è un calcolo molto semplice, ed è del tutto irrilevante, una volta che si inizia a tener conto di fattori come il materiale, la gravità, le pareti che non sono diritti, ecc ...

180-A non funziona in tutti i casi, a meno che non si sta solo lavorando un rimbalzo su una superficie superiore quando X è in aumento.

Una direzione testa è il forum XNA o sollevare codice di esempio XNA. Si tratta di C # ed è per i giochi di costruzione. Non sto affermando che si vuole costruire i tuoi giochi in XNA, ma è un grande strumento, ed è gratuito.

Questa è davvero una domanda di fisica, quindi se non siete un fisico (e dal momento che si sta chiedendo a questa domanda, ho intenzione di prenderlo che non sei) che richiederà un sacco di lettura e di brainstorming per ottenerlo giusto.

questa voce wikipedia per ottenere l'idea di base per la profondità della tua domanda .

Se si desidera solo per renderlo "sembrare plausibile" allora io non mi preoccuperei troppo e usare Bill del Lizard risposta, se si vuole fare bene si avrà abbastanza un'avventura. Non lasciate che questo ti spaventa tho! Buona fortuna!

if(!Collide(Missle, Mainchar)){
(Velocity.x)*-1;
(Velocity.y)*-1;
}

Funziona ed è semplice, buona fortuna.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top