sfondo
Insieme a un amico sto lavorando a un gioco 2D ambientato nello spazio. Per renderlo il più coinvolgente e interattivo possibile, vogliamo che ci siano migliaia di oggetti che fluttuano liberamente intorno, alcuni raggruppati insieme, altri alla deriva nello spazio vuoto.
Sfida
Per liberare il motore di rendering e fisica dobbiamo implementare una sorta di partizionamento spaziale. Ci sono due sfide che dobbiamo superare. La prima sfida è che tutto si sta muovendo, quindi la ricostruzione / aggiornamento della struttura dei dati deve essere estremamente economica poiché dovrà essere eseguita in ogni frame. La seconda sfida è la distribuzione degli oggetti, come detto prima potrebbero esserci gruppi di oggetti insieme e vasti frammenti di spazio vuoto e, a peggiorare le cose, non c'è limite allo spazio.
Tecnologie esistenti
Ho esaminato tecniche esistenti come alberi BSP, QuadTree, alberi kd e persino alberi R, ma per quanto ne so, queste strutture di dati non si adattano perfettamente dall'aggiornamento di molti oggetti che si sono spostati su altre celle è relativamente costoso.
Quello che ho provato
Ho preso la decisione che ho bisogno di una struttura di dati più orientata al rapido inserimento / aggiornamento piuttosto che alla restituzione del minor numero possibile di hit a seguito di una query. A tale scopo ho reso implicite le celle in modo che ogni oggetto, data la sua posizione, possa calcolare in quale cella dovrebbe essere. Quindi uso un HashMap
che mappa le coordinate della cella su un ArrayList
(il contenuto della cella). Funziona abbastanza bene poiché non c'è memoria persa su celle "vuote" ed è facile calcolare quali celle ispezionare. Tuttavia, la creazione di tutte quelle ArrayList
s (nel peggiore dei casi N) è costosa e quindi sta crescendo HashMap
molte volte (sebbene ciò sia leggermente mitigato dandogli una grande capacità iniziale).
Problema
OK, quindi funziona ma non è ancora molto veloce. Ora posso provare a micro-ottimizzare il codice JAVA. Tuttavia, non mi aspetto troppo dal momento che il profiler mi dice che la maggior parte del tempo viene impiegato nella creazione di tutti quegli oggetti che utilizzo per memorizzare le celle. Spero che ci siano altri trucchi / algoritmi là fuori che lo rendono molto più veloce, quindi ecco come appare la mia struttura dati ideale:
- La priorità numero uno è l'aggiornamento / ricostruzione rapida dell'intera struttura dei dati
- È meno importante dividere gli oggetti in bidoni di dimensioni uguali, possiamo disegnare alcuni oggetti extra e fare qualche controllo extra di collisione se ciò significa che l'aggiornamento è un po 'più veloce
- La memoria non è molto importante (gioco per PC)