Dove dovrebbe essere posizionata la logica di rilevamento delle collisioni?


19

Sto sviluppando un piccolo motore di gioco 2D. I personaggi hanno un metodo di pittura che attualmente effettua le seguenti operazioni:

  1. Calcola la nuova posizione del personaggio secondo la sua velocità, ecc.
  2. Aggiorna la cella della griglia di collisione **
  3. Disegna il personaggio nella nuova posizione

** Ho creato una griglia di collisione per ridurre il numero di controlli di intersezione

Ora l'algoritmo di base che ho pensato per rilevare la collisione è:

For Each Character
    Check intersection with characters in surrounding 8 cells

Posso semplicemente inserire questo codice nel metodo paint. Ma ecco il problema che prevedo.

Supponiamo che due caratteri A e B si trovino nelle celle adiacenti nella griglia di collisione. Ora, secondo l'algoritmo sopra riportato nell'iterazione del carattere A, rileverà che si è scontrato con B. Nell'iterazione per il carattere B, rileverà che si è scontrato con A.

Ma ho idea che quando A rileva che si è scontrato con B, dovrebbe informare B che si è scontrato con A. Ciò risparmierebbe molti paragoni quando ci sono più di 2 attori in collisione. Ma non sono sicuro di come gestirlo. Penso che invece di ogni personaggio che controlla la sua collisione, dovrei verificare la collisione all'interno del circuito di gioco.

Questo approccio sarebbe corretto? Come hai gestito questo tipo di problema? Ho pensato alla cosa della griglia di collisione da solo. Esistono alternative alla logica della griglia di collisione?


Mi dispiace nitpick, ma in una biblioteca di fisica 2D specializzata. La fisica del gioco è di solito molto approssimativa, quindi qualsiasi soluzione che non rende il gioco non giocabile va bene, ma se vuoi risolverlo correttamente usa solo la fisica specializzata come Box2D ... :-D
user712092

Risposte:


14

L'approccio usuale per il rilevamento delle collisioni è di non avere A o B per rilevare le collisioni da soli.

Invece, prima devi spostare tutti gli oggetti, quindi un sistema di collisione separato cerca le collisioni tra tutte le coppie di oggetti, raccontando a ogni oggetto le cose con cui è entrato in collisione, e infine renderizza tutti gli oggetti.

Quindi, in sostanza, invece di "spostare, controllare le collisioni, disegnare" all'interno della funzione Paint (), si divide "sposta" e "disegna" in funzioni separate che si chiamano separatamente (prima "sposta" per ogni oggetto, quindi "disegnare" per ogni oggetto). E tra quelli, controlla le collisioni.

Nota avanzata: se uno qualsiasi dei tuoi oggetti si muove in risposta a collisioni rilevate, potrebbe essere necessario ripetere il passaggio "cerca collisioni tra tutte le coppie di oggetti", nel caso in cui la risposta alla collisione di un oggetto causi un'altra collisione.


Questo è il modo corretto di fare le cose. Lascia che gli oggetti gestiscano le loro responsabilità e il sistema di collisione dovrebbe decidere cosa succede quando incontrano un ostacolo. Puoi anche avere un rettangolo / cilindro di collisione (2d / 3d) attorno ai tuoi personaggi come una specie di innesco iniziale.
James P.

Grande! Per quanto riguarda la nota avanzata, le collisioni non dovrebbero essere ricontrollate solo per gli oggetti che si muovono in reazione alla collisione e gli oggetti con cui si scontrano nella nuova posizione? Ci sarà una catena di controlli ma eviterà di controllare la collisione per tutti gli oggetti.
Cracker,


1

Eseguo un loop per tutti i miei personaggi nel loop di gioco come dici tu.

Il modo in cui lo faccio è con uno stato su ciascuno dei miei personaggi, quindi se A e B si scontrano mentre A sta controllando la collisione A e B sono impostati per colpire. all'inizio del ciclo di B controlla se è già stato colpito, se così id non esegue il ciclo.

Metto il codice dell'affetto nel loop in modo che qualsiasi azione che dovrebbe essere intrapresa su B sia avvenuta nel loop di A, quindi non ci dovrebbe essere motivo per cui B verifichi poiché ciò potrebbe incasinare l'esito della collisione, ma potrebbe essere diverso per te .


Ma in questo caso quando A rileva l'intersezione con B, B.hit sarà impostato su true e quindi B non verificherà QUALSIASI intersezione. Ma se un altro personaggio C si interseca con B, B non lo rileverà?
Cracker,

Scusa, capito. Poiché A non si interseca con C, C.hit sarà comunque falso. B non verificherà la presenza di collisioni. Ma C controllerà e passerà le informazioni a B che c'è una collisione tra B e C. Cool!
Cracker,

Ma immagino che se tutte le A, B e C si intersecano tra loro, ci sarebbe un problema. A imposta B.hit e C.hit su true. B e C sapranno che si sono scontrati con A. Ma poiché la loro proprietà di successo è vera, non controlleranno la collisione. La collisione tra B e C passerà inosservata.
Cracker,

È possibile intrufolarsi in un metodo simile mettendo ogni oggetto di collisione in una raccolta di qualche tipo, quindi controllando solo la collisione con le cose che seguono l'oggetto nella raccolta. IE: A controlla vs B, C, D; B controlla vs C, D; C controlla contro D. Ognuno dietro non ha bisogno di essere controllato in quanto era già controllato dal turno dietro. Non abbastanza veloce come saltare completamente la collisione dell'elemento, ma utile comunque.
Lunin,
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.