Come posso rappresentare i proiettili in un videogioco?


14

Sto realizzando un semplice gioco sparatutto fisso, simile a "Galaga" ,) come parte di una presentazione che sto facendo. Mi chiedo quali strategie e strutture dati utilizzerebbero le persone per localizzare i proiettili, come i laser sparati dall'astronave. Un'implementazione semplicissima che ho usato in precedenza è quella di rappresentare ogni singolo proiettile come punto e controllare le collisioni con tutti gli oggetti nella scena.

Tuttavia, questo sembra costoso, in grandi scene con molti proiettili; Mi chiedo quali altri tipi di strategie o implementazioni vengano utilizzate per questo tipo di caso d'uso. Cosa usano i giochi come FPS per tracciare i proiettili (proiettili, proiettili, ecc.)?


5
Molti giochi FPS presuppongono che i proiettili siano istantanei, ma ci sono quelli che calcolano le traiettorie e il tempo di viaggio.
John McDonald,

2
+1 questa è una grande domanda, e non la limiterei nemmeno a 3d.
ashes999,

Risposte:


8

Per proiettili molto veloci (come laser o proiettili), potresti usare un raggio .

Un raggio ha un punto iniziale e un punto finale. Una struttura di dati (molto minima) per un raggio è:

struct Ray
{
  Vector3f start, end ;
} ;

Somiglia a questo:

inserisci qui la descrizione dell'immagine

(Potresti anche memorizzare nella cache il vettore di direzione e la lunghezza, ma ho usato un defn molto semplice sopra).

Se il raggio è un raggio laser che viaggia alla velocità della luce, dovresti solo persistere il raggio (come iniziare dall'ugello della pistola e finire su un muro da qualche parte) per un paio di fotogrammi. Qualunque cosa intersechi il raggio ogni fotogramma subisce danni.

Se il raggio è un proiettile più lento (come un proiettile, ad esempio), la distanza percorsa dal proiettile su un timestep viene modellata dal raggio. Il punto iniziale è dove si trova il raggio all'inizio del fotogramma e il punto finale è dove sarà il raggio dopo che il fotogramma è terminato. Qualunque cosa sulla strada del raggio del proiettile viene danneggiata dal proiettile.

I raggi possono essere efficacemente scontrati con sfere, aabbs, scafi convessi ecc. Controlla il mio progetto Hullinator per un programma in esecuzione (CTRL + Click to fire rays)


1
Un raggio non funziona molto bene per molti proiettili. Ad esempio, qualsiasi proiettile che può essere lanciato, come i gusci dei serbatoi. I raggi sono comunque ottimi per i proiettili a tiro dritto.
MichaelHouse

Bene, se il guscio si muove in modo estremamente lento (rispetto a un proiettile o un laser), allora sì lo
modellerei

7
Tecnicamente, un raggio è un punto di partenza e una direzione. Questo può essere determinato CON un punto iniziale e un altro punto, ma questo non fa parte della sua definizione. Per definizione, i raggi sono infiniti e non hanno un punto finale.
Casey Kuball,

1
Hai ragione, quello che ho descritto è in realtà un segmento di linea , ma la maggior parte delle persone li chiama raggi quando parlano del rilevamento delle collisioni.
Bobobobo,

3

L'uso di un raggio funziona bene per proiettili che viaggiano istantaneamente come proiettili. Per i proiettili che hanno una velocità più lenta come il tipo di cui farai uso per il tuo gioco spaziale, ha senso tracciare semplicemente la loro posizione nel mondo di gioco come faresti con qualsiasi altra entità. Quello che faccio spesso è avere una classe base chiamata Entità che contiene le proprietà di qualsiasi oggetto di gioco duraturo: posizione, rotazione, scatola di collisione, ecc. Il mio giocatore guidato e proiettili ereditano quindi questo e il mio mondo di gioco deve solo sapere come affrontare l'entità superclasse, non ogni singolo tipo di entità.

Per aumentare le prestazioni è molto comune tenere un pool intorno per tutti gli oggetti che creerai e distruggerai spesso. Quando è necessario un nuovo proiettile da estrarre da questo pool, modificare il nuovo proiettile in base alle esigenze e restituirlo al pool quando è scaduto.


2

Quando si desidera ottimizzare il rilevamento delle collisioni, è possibile memorizzare tutti gli oggetti di gioco in un albero bidimensionale o tridimensionale . Questa struttura di dati rende molto efficiente il recupero di tutti gli oggetti in una determinata area.

Gli alberi binari hanno tuttavia lo svantaggio di degenerare facilmente quando gli oggetti vengono aggiunti, rimossi e cambiano posizione, quindi dovrai bilanciarlo automaticamente .

Un compromesso che sarebbe più facile da implementare ma non altrettanto efficace sarebbe usare un approccio basato su blocchi. Dividi il campo di gioco in cubi e tieni traccia di quali oggetti toccano ciascun cubo. Quando controlli le collisioni con un oggetto, devi solo confrontarlo con gli elenchi degli oggetti dei cubi che sta toccando (sostituisci "cubo" con "rettangolo" per un gioco 2d).

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.