Come gestire le collisioni d'angolo in 2D?


22

Sto scrivendo un gioco XNA 2d top down. Fin dal mio primo tentativo sto provando a scrivere le cose di fisica e di collisione per impararlo.

Ogni volta che il mio personaggio di sprite del giocatore tenta di spostarsi in una posizione in cui i suoi confini si intersecano con il bordo di un muro, immagino un angolo di rimbalzo (angolo di incidenza = angolo di riflessione) e faccio rimbalzare il giocatore dal muro ed evitare la collisione .

Ho difficoltà a capire come gestire la situazione del mio sprite che si interseca con due bordi del muro simultaneamente anche se, ad esempio, colpisce un angolo.

collisione d'angolo

Il mio codice attualmente mi dice che due bordi del muro sono stati intersecati ma non quale bordo avrebbe colpito per primo e quindi quale bordo rimbalzare.

Qual è il test matematico per scegliere quale bordo rimbalzare? È evidente quando lo guardo, ma sto lottando per capire il test di matematica per questo.



Grazie Tetrad. L'ho visto ma sembrava che la palla si sarebbe comportata diversamente dal mio problema rettangolare. Nel caso illustrato sopra lo sprite rettangolare avrebbe colpito il bordo inferiore del muro e rimbalzato su di esso. Il bordo laterale del muro non sarebbe mai entrato nell'equazione. Semplicemente non so come esprimerlo nel codice e prendere quella decisione.
TerryB,

Risposte:


9

Se si calcola che punto della Wallla Player Spritesi è spostato, probabilmente si può basare sul delta del coordinate xey degli angoli che si intersecano. Spero che abbia un senso, non riesco a pensare a un modo migliore per esprimerlo.

Quindi, ad esempio, se guardi il tuo diagramma. Prendi il xvalore dell'angolo in alto a sinistra di Player Sprite(dopo lo spostamento) e sottrai il xvalore dell'angolo in basso a destra di Wall. Fai la stessa cosa per i yvalori e poi vedi quale è più grande. La chiave è che se uno è più grande dell'altro, Player Spriteprobabilmente si intersecano da quel lato.

Ecco un esempio di immagine (questa è una sottosezione della tua immagine con le mie linee aggiunte):

esempio di intersezione

Ora, vedi qui che la linea blu è più grande della linea verde. In questo caso la linea blu è anche sul lato da cui Player Spriteci si aspetta che rimbalzi.

Se i due valori sono uguali, colpiscono proprio nell'angolo.

Ora, c'è un leggero problema nel farlo in questo modo. Se Player Spritesta viaggiando molto velocemente o la collisione è molto vicina all'angolo, è possibile che Player Spritepossa andare oltre nella Walldirezione sbagliata. In tal caso, probabilmente dovrai controllare la velocità dell'oggetto in movimento. (Vedi la risposta di Nathan Reed .)

Nota: penso che sto essenzialmente cercando di descrivere il rilevamento delle collisioni SAT menzionato da @Blau, ma ho trascorso molto tempo a scriverlo, quindi lo pubblicherò comunque. Spero che ti possa aiutare.


Grazie Drackir! E immagino che se il mio muro è ruotato rispetto allo sprite è un po 'più complicato ma si applica lo stesso principio. Cerca il vettore di spostamento di lunghezza minima che significherebbe che lo sprite non si scontrerebbe con il muro. Quindi usa il muro normale per quel vettore come il mio per rimbalzare.
TerryB,

@TerryB - La rotazione aggiunge un po 'più di complessità. Potresti voler leggere su scatole di delimitazione allineate agli assi (AABB). Fondamentalmente, usi ancora lo stesso principio di cui sopra testando la scatola più piccola in cui si inserirà l'oggetto ruotato, ma i cui assi sono allineati agli assi cartesiani. Immagina se avessi un quadrato e lo ruotassi di 45 gradi per renderlo un diamante. Calcolare la collisione su ciò sarebbe difficile e costoso, quindi prima controlla se l'oggetto è persino vicino usando l'AABB che sarebbe un quadrato in cui ogni punto del diamante tocca ogni lato nel mezzo.
Richard Marskell - Drackir,

Quindi, quando sai che è vicino, puoi fare i calcoli più costosi per vedere se si intersecano negli angoli (che probabilmente dovrebbe essere un'altra domanda del tutto :)).
Richard Marskell - Drackir,

1
-1 poiché lo spostamento minimo non fornisce sempre la risposta corretta a "quale bordo si è scontrato per primo"; vedi la mia risposta.
Nathan Reed,

@NathanReed - Ecco perché ho menzionato il controllo della velocità nel mio paragrafo "Ora, c'è un piccolo problema a farlo in questo modo".
Richard Marskell - Drackir,

15

Lo spostamento minimo non fornisce sempre la risposta giusta per quale bordo è stato colpito per primo. Considera questo caso:

caso che interrompe l'algoritmo di spostamento più breve

Questo accade quando la velocità è abbastanza alta da far spostare il blocco piuttosto lontano durante un fotogramma. Per rilevare correttamente quale bordo è stato colpito per primo, è necessario impostare un'equazione lineare da risolvere per il momento della collisione con ciascun bordo. In questo caso, descritto nel diagramma del PO, le equazioni rilevanti sono:

timeXCollision = (player.left - wall.right) / -player.velocity.x
timeYCollision = (wall.bottom - player.top) / player.velocity.y

(Questo presuppone un sistema di coordinate X-destra, Y-su.) In generale, dovresti usare i segni dei componenti X e Y di player.velocity per determinare quale coppia di bordi deve essere testata. Ad ogni modo, una volta calcolati i tempi di collisione, la prima delle due è la collisione che devi gestire.


1
Potresti fornire un esempio su come implementare le tue due variabili?
BjarkeCK,

1

È necessario il rilevamento delle collisioni SAT

Fondamentalmente è necessario cercare il vettore di spostamento minimo che sottratto a uno degli oggetti consente loro di non intersecarsi.

Nella tua immagine lo spostamento minimo è il segmento arancione.

inserisci qui la descrizione dell'immagine


4
-1 poiché lo spostamento minimo non fornisce sempre la risposta corretta a "quale bordo si è scontrato per primo"; vedi la mia risposta.
Nathan Reed,

chi lo sta chiedendo?
Blau,

La domanda è quella. "Il mio codice attualmente mi dice che due bordi del muro sono stati intersecati, ma non quale bordo avrebbe colpito per primo e quindi quale bordo rimbalzare."
Nathan Reed,

primo? il problema non è quello che è il primo, si scontra con i due bordi contemporaneamente, ... la questione è quale bordo rimbalzare, hai scelto un metodo che è buono per te, ho scelto un metodo che è buono per me, entrambi sono validi
Blau

1
Se vuoi prendere una decisione di progettazione per far scivolare gli oggetti l'uno accanto all'altro in questo modo, come se fossero arrotondati o smussati agli angoli, questa è la tua decisione e potrebbe essere la cosa giusta per il tuo gameplay. Ma non penso che la domanda sia su una decisione di progettazione; sta chiedendo matematicamente come rimbalzare reciprocamente i rettangoli allineati agli assi. Questa non è una questione di interpretazione; questo problema di matematica ha una risposta chiara e corretta a quale vantaggio rimbalzare.
Nathan Reed,

0

Ha risposto a una domanda simile qui

Ti consigliamo di verificare le posizioni precedenti-

Ad esempio: se la parte sinistra era precedentemente alla destra della parte destra e si sta scontrando, si è verificata una collisione con la mano destra.

Se lo fai, risolvi semplicemente le collisioni sull'asse y, controlla se stai entrando in collisione con qualcosa, quindi risolvi le collisioni sull'asse x.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.