Estou fazendo um jogo simples de tiro fixo, semelhante ao "Galaga" ,) como parte de uma apresentação que estou fazendo. Estou imaginando que estratégias e estruturas de dados as pessoas usariam para rastrear projéteis, como lasers disparados da nave espacial. Uma implementação super simples que eu usei antes é apenas representar cada projétil como um ponto e verificar colisões com todos os objetos na cena.
No entanto, isso parece caro, em grandes cenas com muitos projéteis; Estou imaginando que outros tipos de estratégias ou implementações são usadas para esse tipo de caso de uso. O que jogos como o FPS usam para rastrear projéteis (balas, cartuchos de tanque, etc.)?
game-design
design-patterns
Polaris878
fonte
fonte
Respostas:
Para projéteis muito rápidos (como lasers ou balas), você pode usar um raio .
Um raio tem um ponto inicial e um ponto final. Uma estrutura de dados (mínima) para um raio é:
Se parece com isso:
(Você também pode armazenar em cache o vetor e o comprimento da direção, mas usei uma definição muito simples acima).
Se o raio é um feixe de laser que viaja na velocidade da luz, você apenas o mantém (como começar no bico da pistola e terminar em uma parede em algum lugar) por alguns quadros. Qualquer coisa que cruze o raio de cada quadro sofre danos.
Se o raio é um projétil mais lento (como uma bala, por exemplo), a distância que a bala percorreu ao longo de um passo temporal é modelada pelo raio. O ponto inicial é onde o raio está no início do quadro e o ponto final é onde o raio estará após o término do quadro. Qualquer coisa no caminho do raio da bala é danificada pela bala.
Os raios podem ser colididos com eficiência com esferas, esferas, cascos convexos etc. Confira meu projeto Hullinator para obter um programa de execução real (CTRL + Clique para disparar raios)
fonte
Usar um raio funciona bem para viajar instantaneamente projéteis, como balas. Para projéteis com velocidade mais lenta, como o tipo que você utilizará para o seu jogo espacial, faz sentido simplesmente rastrear sua posição no mundo do jogo como faria com qualquer outra entidade. O que costumo fazer é ter uma classe base chamada Entidade, que contém propriedades de qualquer objeto duradouro do jogo - posição, rotação, caixa de colisão, etc. a superclasse Entidade, não cada tipo individual de entidade.
Para aumentar o desempenho, é muito comum manter um pool para todos os objetos que você criará e destruirá com frequência. Quando você precisar de um novo projétil que retiraria desse pool, modifique o novo projétil conforme necessário e retorne-o de volta ao pool quando ele expirar.
fonte
Quando você deseja otimizar a detecção de colisões, pode armazenar todos os objetos do jogo em uma árvore bidimensional ou tridimensional . Essa estrutura de dados torna muito eficiente recuperar todos os objetos em uma determinada área.
No entanto, as árvores binárias têm a desvantagem de degenerar facilmente quando objetos são adicionados, removidos e alteram suas posições, portanto, você precisará balancear automaticamente .
Um compromisso que seria mais fácil de implementar, mas não seria tão eficiente, seria usar uma abordagem baseada em partes. Divida o campo de jogo em cubos e acompanhe quais objetos estão tocando em cada cubo. Ao verificar colisões com um objeto, você só precisa compará-lo com as listas de objetos dos cubos em que está tocando (substitua "cubo" por "retângulo" para um jogo em 2D).
fonte