Considere uma grade 2D de peças e uma esfera aproximada de coordenadas - centralizada no jogador - que representa a linha de visão. O objetivo é bloquear a linha de visão além dos obstáculos (ou seja, paredes).
É relativamente simples determinar se uma célula individual na esfera de visão é visível: lance um raio do jogador para a célula alvo, usando o de Bresenham - se uma das células sobrepostas entre o jogador e o alvo for um obstáculo, a célula alvo não é visível.
Agora, meu primeiro pensamento foi percorrer todas as células da grade na linha de visão - mas isso me parece ineficiente. Por exemplo, se o jogador estiver ao lado de uma parede e você determinar que a célula além da parede não é visível, poderá determinar todas as células no raio depois que não serão visíveis.
Também considerei lançar um raio para cada célula ao longo do perímetro da esfera de visão e iterar cada célula ao longo de cada raio - mas então eu processaria algumas células mais de uma vez.
Existe uma maneira mais eficiente de fazer isso?
Embora a iteração de ~ 50 células por turno seja um cálculo relativamente leve, estou buscando velocidade - o objetivo é ser capaz de pedalar alguns turnos por segundo na reprodução automática. Então, quanto mais eficiente eu puder fazer isso, melhor.
fonte
Respostas:
Você pode tentar lançar "arcos de sombra" para cobrir áreas maiores de uma só vez. Embora os detalhes reais estejam um pouco envolvidos, Eric Lippert tem uma explicação muito detalhada (com demonstração ao vivo do Silverlight) em http://blogs.msdn.com/b/ericlippert/archive/2011/12/12/shadowcasting-in -c-part-one.aspx .
fonte
Eu implementei o algoritmo sugerido por Jimmy.
Vídeo do código em ação aqui: https://youtu.be/lIlPfwlcbHo
fonte