Collisione 2D veloce e precisa


17

Sto lavorando a uno sparatutto topdown 2d e ora ho bisogno di andare oltre il mio sistema base di collisione con rettangolo di delimitazione.

Ho grandi livelli con molti sprite diversi, ognuno dei quali ha forme e dimensioni diverse. Le trame per gli sprite sono tutti file png quadrati con sfondi trasparenti, quindi ho anche bisogno di un modo per avere una collisione solo quando il giocatore entra nella parte colorata della trama e non sullo sfondo trasparente.

Ho intenzione di gestire la collisione come segue:

  1. Controlla se ci sono sprite nel raggio del giocatore
  2. Esegui un test di collisione con rettangolo di selezione
  3. Fai una collisione accurata (dove ho bisogno di aiuto)

Non mi dispiace per le tecniche avanzate, poiché voglio farlo bene tenendo conto di tutti i miei requisiti, ma non sono sicuro di come affrontarlo. Quali tecniche o persino librerie provare. So che probabilmente dovrò creare e memorizzare un qualche tipo di forma che rappresenti accuratamente ogni sprite meno lo sfondo trasparente.

Ho letto che per pixel è lento, quindi dati i miei grandi livelli e il numero di oggetti non penso che sarebbe adatto. Ho anche esaminato Box2d, ma non sono stato in grado di trovare molta documentazione o alcun esempio di come farlo funzionare e funzionare con SFML.

Risposte:


18
  1. Primo passo, crea una griglia e aggiornala per ogni oggetto che si sposta.
  2. Controlla solo le collisioni tra oggetti negli stessi quadrati.
  3. Controlla se il rettangolo di selezione degli oggetti si interseca (il loro rettangolo di contenimento).
  4. Verifica la perfetta collisione dei pixel usando una versione a bassa risoluzione del contorno (vedi Fisica di gioco).
  5. Esegui un normale controllo della traccia del contorno come descritto in Game Physics (Q 2)

Passo 1:

Crea un array griglia 2d. Ogni oggetto sa quali quadrati occupa per la sua posizione x, y e la sua larghezza e altezza. Se un oggetto viene spostato, si cancella dalla vecchia piazza e aggiorna la nuova piazza che sta occupando.

Questo richiede solo O (n) in totale per n oggetti. Per qualsiasi oggetto specifico O (1).

Passo 2:

Esegui tutti i controlli per le collisioni tra oggetti negli stessi quadrati. Non è necessario eseguire test per le collisioni tra oggetti in quadrati diversi. Un oggetto può occupare fino a quattro quadrati se è di dimensioni medie. Ciò significa pochissimi controlli.

Passaggio 3:

Controlla l'intersezione tra i rettangoli degli oggetti. Se non esiste alcun incrocio, fermarsi.

Step 4:

Controlla le collisioni perfette dei pixel tra i contorni degli oggetti solo all'interno dell'area di intersezione. Dovrebbe essere abbastanza veloce. In caso contrario, crea un array booleano 2d a bassa risoluzione e controllalo prima, se trovi delle collisioni lì, dovrai solo controllare un piccolo segmento nell'array 2d ad alta risoluzione risparmiando un po 'di tempo prezioso.

Si prega di leggere questo concetto per come dividere il mondo di gioco in una griglia di quadrati:

Realizzare un efficiente sistema di rilevamento delle collisioni

Si prega di leggere questo per intuizione su come rilevare le collisioni perfette dei pixel .

Fisica di gioco / rilevamento delle collisioni 2D AS3

Puoi migliorare significativamente le prestazioni:

  1. Salvataggio di una versione a bassa risoluzione (1/16) della struttura da verificare per prima.

  2. Controllando solo l'area in cui le due rects si intersecano.

  3. dividendo il contorno approssimativamente in segmenti e controllando prima solo le collisioni tra i segmenti.

Non esitate a commentare e io elaborerò.

controllare nell'area di intersezione


1
Come ha detto Arthur, sostituisci i tuoi passaggi 1. e 2. con una griglia e, per quanto riguarda il rilevamento accurato delle collisioni, potresti utilizzare una versione a bassa risoluzione delle tue immagini.
Markus von Broady,

1
E se ne hai davvero bisogno, potresti anche usare una tecnica simile alla mia risposta qui: gamedev.stackexchange.com/questions/38481/…
Markus von Broady

Markus sottolinea una buona idea. Dovresti usare un array booleano 2d o un array 1d che viene trattato come 2d e potresti salvare 1/2 1/4 1/8 versioni a bassa risoluzione di quell'array per velocizzare le cose. Questo probabilmente non sarà necessario poiché il calcolo su array booleani 2d è molto veloce. È ancora uno strumento utile da avere.
Wolfdawn,

Se il giocatore è interamente contenuto all'interno di un quadrato sulla griglia, puoi controllare solo contro gli oggetti in quel quadrato. Il giocatore può essere in quattro caselle adiacenti contemporaneamente. È questo che vuoi dire? Se intendi l'intersezione tra i rettangoli, sì, devi solo verificare la presenza di collisioni se si intersecano.
Wolfdawn,

1
Spero che l'aggiornamento aiuti a chiarire le cose. Una volta che hai scritto del codice, puoi pubblicarlo nella revisione del codice e collegarci per i commenti. codereview.stackexchange.com
wolfdawn
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.