Considere una cuadrícula 2D de fichas y una esfera aproximada de coordenadas, centrada en el jugador, que representa la línea de visión. El objetivo es bloquear la línea de visión más allá de los obstáculos (es decir, paredes).
Es relativamente simple determinar si una celda individual en la esfera de la vista es visible: lanza un rayo desde el jugador a la celda objetivo, usando Bresenham, si una de las celdas superpuestas entre el jugador y el objetivo es un obstáculo, la celda objetivo no es visible.
Ahora, mi primer pensamiento fue iterar a través de todas las celdas de la cuadrícula en la línea de visión, pero esto me parece ineficiente. Por ejemplo, si el jugador está parado al lado de una pared, y usted determina que la celda más allá de la pared no es visible, puede determinar que todas las celdas en el rayo después de eso no serán visibles.
También consideró lanzar un rayo a cada celda a lo largo del perímetro de la esfera de la vista e iterar cada celda a lo largo de cada rayo, pero luego estaría procesando algunas celdas más de una vez.
¿Hay una manera más eficiente de hacer esto?
Si bien iterar ~ 50 celdas por turno es un cálculo relativamente liviano, voy por la velocidad: el objetivo es poder realizar un ciclo de unos pocos turnos por segundo en el juego automático. Entonces, cuanto más eficiente pueda hacer esto, mejor.
fuente
Respuestas:
Podría intentar lanzar "arcos de sombra" para cubrir áreas más grandes a la vez. Si bien los detalles reales son un poco complicados, Eric Lippert tiene una explicación muy detallada (con una demostración en vivo de Silverlight) en http://blogs.msdn.com/b/ericlippert/archive/2011/12/12/shadowcasting-in -c-part-one.aspx .
fuente
He implementado el algoritmo sugerido por Jimmy.
Video del código en acción aquí: https://youtu.be/lIlPfwlcbHo
fuente