Come posso creare particelle che reagiscono al giocatore e ai nemici?


38

Attualmente sto realizzando un gioco con il mio motore di gioco che ho scritto in C ++ e sto usando l'SDK directx più recente.

Il gioco è uno sparatutto spaziale dall'alto verso il basso (con una svolta piuttosto interessante) e sto cercando di avere una sorta di effetto nebulosa attraverso il quale il giocatore volerà. Voglio davvero provare a inchiodare quella piacevole sensazione tattile di centinaia di particelle che si allontanano dalla nave giocatore mentre vola su di esse. Un po 'come il modo in cui le particelle si allontanerebbero dal giocatore in Geomtry Wars su XBLA.

Sono un programmatore esperto quando si tratta di C ++. Non so, tuttavia, come iniziare a implementare questo effetto. Qualcuno ha idee interessanti o scelte di design che potrei voler esaminare? Sentiti libero di rispondere a qualsiasi grado di profondità tu voglia.

Risposte:


65

È una bella idea. Avresti bisogno di una sorta di gradiente di diffusione intorno alla tua nave. Ci sono tre modelli fisici a cui posso pensare che potresti desiderare:

  1. Vuoi che sembri quasi un mezzo liquido, dove il gradiente di pressione si riequilibra, cioè una volta che hai passato alcune particelle si spostano di nuovo nella tua scia (come l'acqua dietro una barca). In questo caso, le posizioni delle particelle sono assolute ed è solo la loro relazione con il giocatore che modifica temporaneamente la loro posizione di rendering . È un po 'come quando si passa una lente d'ingrandimento spessa sulle cose e la diffrazione sembra farle muovere, ma solo fino a quando non si sposta il vetro. In questo caso, la tua nave è il vetro.

  2. Se vuoi che si allontanino dalla nave e continuino a muoversi una volta che si sono mossi. Questo è come la fisica standard nello spazio generalmente vuoto dove non ci sono (o molto piccoli) gradienti di pressione.

  3. Vuoi allontanare rapidamente le particelle dalla nave mentre si avvicina, come in (1) e (2), ma una volta che la nave è andata via, le particelle si riequilibreranno lentamente per essere equidistanti sulla tua scia.

Comune a tutte e tre le soluzioni : è necessario disporre di un campo di diffusione che si muova con la propria nave. In questo esempio lo renderemo circolare. Quindi si rileva il vettore, lo si chiama v1, tra la nave e ogni particella all'interno di quella regione. Spingi via la tua particella lungo quel vettore. La forza con cui lo spingerai via dipenderà dalla sua distanza dalla nave: usare 1 - v1.magnitude. Questa formula ti darà una forza lineare, tuttavia potresti modificarla per usare qualcos'altro come una curva di forza circolare che diminuisce in forza verso i bordi. Questo darebbe più uno sguardo come se ci fosse un gradiente di pressione sferico piuttosto che circolare attorno alla nave.

Per la soluzione 1 : tutto ciò che fai ora è modificare la posizione di rendering di quella particella (cioè la posizione di sprite) su ogni aggiornamento di rendering , con questo vettore. Poiché lo stai facendo in questo modo, questo è puramente un effetto di rendering e non ha alcun effetto sulla posizione mondiale effettiva della particella. Quindi aggiungi la posizione del mondo all'offset di rendering (v1) e ora hai particelle ben spostate mentre ti muovi verso di loro o accanto a loro e ripristini uniformemente le particelle mentre passi (dietro di te).

Per la soluzione 2 : anziché applicare semplicemente v1 alla posizione della vista, applicarlo su ogni aggiornamento logico , alla posizione della particella. Quindi p1.position += v1. Quindi stai applicando una forza accelerativa alla particella, che si traduce in velocità. Probabilmente, vorrai che la velocità di ogni particella venga smorzata in modo che rallentino gradualmente e si fermino una volta superata. Puoi vedere come questa soluzione si tradurrà in particelle ammucchiate nella tua nebulosa, perché non si ridistribuiranno mai. Non sono molto realistico, ne sono certo, poiché le nebulose hanno gradienti di pressione al loro interno, non importa quanto deboli nella realtà.

Per soluzione 3: Come per (2), ma in questo caso dovrai ridiffondere le particelle. Per farlo facilmente è un po 'un approccio di forza bruta, ma poiché queste sono solo particelle e quindi piacere per gli occhi, probabilmente non hai bisogno di coprire una vasta area di interesse (probabilmente solo un raggio di playerPosition + maxPlayerSpeedPerTick o qualsiasi altra cosa l'area rettangolare lo circoscrive, per scopi logici). Ogni particella applicherà una forza su ogni altra particella all'interno dell'area di interesse. Applicheranno forze basate, ancora una volta, sulle loro distanze l'una dall'altra. Calcola tutte le forze interparticulari in un unico passaggio attraverso l'area di interesse, quindi applica tutte le forze in un solo passaggio. Infine, assicurati di eseguire questa elaborazione della forza tra le particelle solo su particelle a velocità zero. E una volta che una determinata particella raggiunge una velocità minima,

Ci sono tutti i tipi di formule di diffusione ecc. Là fuori, ma penso che in questo caso una soluzione semplice funzioni meglio.


Amico, purtroppo al momento non ho la reputazione di votare la tua risposta (e sarei in grado di farlo solo una volta, il che è meno di quanto meriti). Hai assolutamente inchiodato quello che sto cercando nella tua prima soluzione. Risposta fantastica. Onestamente. Grazie!
Matt McDonald,

Piacere totale Matt, è una buona domanda e vale la pena flettere il cervello!
Ingegnere

Ho anche deciso che con pochissime modifiche al codice avrei potuto applicarlo agli asteroidi più piccoli all'interno di una cintura. Grazie ancora.
Matt McDonald,
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.