Rilevamento di collisioni 2D


11

Supponiamo che io stia usando questo personaggio.

uccello
(fonte: iconbug.com )

Come implementeresti il ​​rilevamento delle collisioni? L'uso di un rettangolo di selezione non sembra essere una buona approssimazione, perché la forma dell'uccello non è in nessun posto vicino a un quadrato.

Stavo pensando di avere una sorta di struttura dati quad tree all'interno dell'oggetto che rappresenta porzioni dell'immagine. Ogni foglia può essere false(nel caso in cui copra lo spazio bianco / trasparente all'esterno dell'uccello) o true(nel caso in cui rappresenti un'area dell'uccello, ad esempio becco, occhio, ecc.). Quindi in qualche modo prova l'unico ostacolo sulla scena per la collisione con l'uccello.

Ma i miei problemi nel mio approccio sono:

  1. Non so come inizializzare l'albero dei quad.
  2. Una volta inizializzato l'albero dei quad, non sono sicuro di come attraversarlo e usarlo quando l'ostacolo si trova all'interno delle coordinate dell'immagine.

Come effettueresti il ​​rilevamento delle collisioni con personaggi non quadrati?

LE: L'altro approccio che ho visto è stato l'uso di più box di delimitazione. Ad esempio, avrei una o poche scatole di delimitazione per il becco, poi alcune per i capelli o la coda. Ma può diventare noioso. Se questo è un approccio valido nel mio caso, come potrei generare quei rettangoli? Dubito che dovrei averli codificati nel mio programma.

LE2: Mi preoccupo di collisioni abbastanza precise. Non riesco a immaginare come un singolo rettangolo di selezione o un cerchio possano almeno approssimare decentemente quella forma, quindi questo approccio non funzionerà.


2
Una nota generale: userei entrambi, un rettangolo di selezione e un controllo più granulare: il controllo granulare avrà una penalità di prestazione più alta, quindi vuoi che venga eseguito il più raramente possibile. Pertanto, prima controlla il rettangolo di selezione e solo se viene colpito, vai a un livello più profondo e prova il tuo approccio più granulare (qualunque cosa sarà).
Philip Allgaier,

Grazie, avevo intenzione di farlo comunque, ma non sono del tutto sicuro di quale dovrebbe essere il "controllo granulare". :)
asincrono il

1
Manca l'unico dettaglio importante: che cosa vuoi fare con esso? Ti interessano le esatte collisioni? Sei felice di approssimare il personaggio con un cerchio? Vuoi che le particelle di polvere si scontrino con gli occhi del personaggio separatamente dagli altri?
Anko,

@Anko Come puoi approssimare quella forma con un cerchio? Mi preoccupo di collisioni abbastanza precise, non molto precise, ma qualcosa che sembrerà buono / naturale-.
asincrono il

1
Come questo . Cosa significano "buono" e "naturale"? È una domanda filosofica?
Anko,

Risposte:


12

Circle Collider. Abbastanza buono per questo direi che a meno che tu non stia facendo qualcosa di stravagante con alcune parti influenzate dalla fisica o la collisione sembrando innaturale, e anche se hai bisogno di dividerlo in più parti, ho una cosa da dirti:

Non complicarti troppo.

Non hai bisogno di una struttura ad albero quad pieno per questo. Basta avere più caselle o cerchi in un array diritto, quindi intersecarli con tutti. Questo non può essere abbastanza critico per le prestazioni e non otterrai così tanto dall'uso di un albero quad.


3
Sì, basta creare una piccola serie di diverse forme se una singola forma non la copre. Ad esempio: i.imgur.com/Dd4yyGN.png
MichaelHouse

Grazie Jonkel e @ Byte56. L'uso di alcune forme sembra la soluzione giusta nella mia situazione. Semplice da implementare, preciso e veloce. Non riesco a credere di essere passato direttamente ai quad senza considerare questo! Uh.
asincrono il

Un collider circolare per il corpo e un rettangolare per il becco, per una maggiore precisione.
Kroltan,

14

Un processo di controllo in due passaggi

Nel primo passaggio, si seleziona il riquadro di delimitazione e, se non vi è alcuna collisione, il test è terminato. In caso di collisione, si passa al secondo passaggio

Al secondo passaggio , se si desidera maggiore precisione e si desidera una vera soluzione perfetta per i pixel, è possibile fare proprio questo, un controllo perfetto per i pixel

Dato che la tua immagine è un PNG (o qualsiasi altro formato di file che contiene un canale alfa), questo sarebbe piuttosto semplice

  1. Calcola l'area di intersezione tra quell'unico oggetto nella scena e l'uccello, generando un semplice rettangolo di intersezione su entrambe le immagini
  2. All'interno di tale intersezione, controlla che ciascun pixel abbia un valore alfa> 0 in ENTRAMBE le immagini
  3. Se esiste uno di questi pixel, hai la collisione. Altrimenti no

Se guardi il tuo canale alfa delle immagini, puoi vedere come ha già tutte le informazioni di cui potresti aver bisogno per una perfetta collisione dei pixel

canale alfa dall'immagine

Le collisioni con pixel perfetti sono generalmente costose, quindi fare una prima stima approssimativa con un rettangolo di selezione o una figura di collisione più dettagliata (come quella suggerita da Anko) può farti risparmiare un po 'di tempo prezioso

Il rettangolo di collisione dettagliato "più fine" Anko ha suggerito:

riquadro di selezione più dettagliato

PS: se la tua immagine ha un alone, un effetto o un altro canale alfa diverso da 0 con cui non vuoi scontrarti, la soglia dell'algoritmo può essere facilmente regolata per adattarla


1
Grazie! Ma non avrò bisogno di una precisione perfetta dei pixel dopo tutto. Ottima risposta però, sarà utile in un secondo momento.
asincrono il

certo amico, sì, la collisione perfetta dei pixel è quasi sempre un eccesso, tranne nei giochi che ne hanno davvero bisogno (come i caccia 2D)
codemonkey

3

Vorrei usare un cerchio per il corpo e un singolo rettangolo per il becco, ma questa è solo la mia opinione. Tuttavia, complicare eccessivamente la geometria della collisione può rallentare l'app, praticamente raddoppiando (o più) il numero di caratteri sullo schermo.


0

Forse potresti usare una specie di poligono / collettore di bordi traballanti.

Non sono sicuro di come funzionerebbe, ma:

due oggetti: oggetto 1: l'uccello (o1), oggetto 2: la cosa che potrebbe colpire l'uccello (o2)

1) Definire una forma di delimitazione che è un poligono che si adatta strettamente al primo oggetto (o1) in questione.

2) Ottenere i bordi di o1, o2 che potrebbero collidersi in modo concepibile senza che si possa scontrare in modo concepibile senza che O2 passi attraverso O1 o viceversa.

Con la posizione e le dimensioni della forma (o2) potresti probabilmente isolare i bordi (di o1) che non possono essere colpiti, sia perché sono "dietro" un altro bordo (di o1) che è più vicino a o2. Se avessi un triangolo rettangolo la cui ipotenusa era rivolta verso l'alto e verso destra e un rettangolo si avvicinava dritto (con il lato lungo lungo l'asse x), puoi dire quali bordi omettere perché sono all'inizio e alla fine i valori y sono entrambi sopra o sotto il rettangolo.

3) Determinare se uno dei punti su un bordo di o2 è uguale a un punto su uno dei bordi di o1 selezionato nel passaggio 2.

questo concetto probabilmente funziona meglio per far collidere poligoni (cioè cose con bordi chiari), ma forse puoi considerare un cerchio come un lato lungo (ad esempio se o2 era un cerchio).

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.