fundo
Juntamente com um amigo, estou trabalhando em um jogo 2D que se passa no espaço. Para torná-lo o mais imersivo e interativo possível, queremos que haja milhares de objetos flutuando livremente, alguns agrupados, outros à deriva no espaço vazio.
Desafio
Para aliviar o mecanismo de renderização e física, precisamos implementar algum tipo de particionamento espacial. Existem dois desafios que temos de superar. O primeiro desafio é que tudo está se movendo para que a reconstrução / atualização da estrutura de dados tenha que ser extremamente barata, pois será necessário realizar todos os quadros. O segundo desafio é a distribuição de objetos, como dito anteriormente, pode haver agrupamentos de objetos juntos e vastos pedaços de espaço vazio. Para piorar ainda mais, não há limites para o espaço.
Tecnologias existentes
Analisei técnicas existentes como BSP-Trees, QuadTrees, kd-Trees e até R-Trees, mas, tanto quanto posso dizer, essas estruturas de dados não se encaixam perfeitamente desde a atualização de muitos objetos que foram movidos para outras células é relativamente caro.
O que eu tentei
Tomei a decisão de que eu precisava de uma estrutura de dados mais voltada para inserção / atualização rápida do que para devolver a menor quantidade possível de ocorrências, dada uma consulta. Para esse efeito, tornei as células implícitas para que cada objeto, dada sua posição, possa calcular em qual célula (s) deve estar. Então eu uso um HashMap
que mapeia as coordenadas da célula para um ArrayList
(o conteúdo da célula). Isso funciona muito bem, pois não há memória perdida nas células 'vazias' e é fácil calcular quais células inspecionar. No entanto, criar todos esses ArrayList
s (pior caso N) é caro e cresce HashMap
muitas vezes (embora isso seja um pouco atenuado, fornecendo uma grande capacidade inicial).
Problema
OK, então isso funciona, mas ainda não é muito rápido. Agora eu posso tentar otimizar micro o código JAVA. No entanto, não estou esperando muito disso, já que o criador de perfil diz que é gasto mais tempo na criação de todos os objetos que eu uso para armazenar as células. Espero que haja outros truques / algoritmos por aí que tornem isso muito mais rápido. Aqui está a aparência da minha estrutura de dados ideal:
- A prioridade número um é a rápida atualização / reconstrução de toda a estrutura de dados
- É menos importante dividir os objetos em compartimentos do mesmo tamanho, podemos desenhar alguns objetos extras e fazer algumas verificações adicionais de colisão, se isso significa que a atualização é um pouco mais rápida
- A memória não é realmente importante (jogo para PC)