Visibilidade 2D

Em alguns jogos, temos que calcular as áreas visíveis a partir de um ponto. Como por exemplo, para simular uma luz de uma lanterna ou saber se o jogador está no campo de visão de um inimigo. Em muitas engines e/ou frameworks já fazem esse serviço por você, mas acho interessante saber como essas mecânicas funcionam.

Constant C e Monaco

Abaixo temos a função que irá resolver boa parte desse problema. Ela retorna, caso haja, o ponto de intersecção entre duas retas, usando a equação paramétrica da reta.

Com a função de intersecção implementada, definimos um ponto inicial e sua direção e testamos com todas as retas do “mapa” escolhendo o ponto mais próximo encontrado.

Abaixo mostro alguns exemplos de como utilizar:

Linear

Neste exemplo, vamos pegar considerar o centro como posição inicial e verificar a direção do mouse.

Radial

Neste outro, consideremos a posição do mouse como inicial e “disparamos” 30 raios a cada 12 graus (360/30), ao redor dele.

Pontos Únicos

Aqui também iremos considerar a posição do mouse como inicial, mas iremos traçar retas apenas até os vértices dos segmentos. Salvamos e ordenamos os ângulos entre o ponto inicial e os vértices únicos. Como esses dados organizados, calculamos as intersecções e desenhamos triângulos, utilizando a informação da linha anterior para “fechar” o triangulo.

Exemplo de Uso

Bom, para finalizar vamos fazer um mashup do que foi aprendido nesse post com o exemplo mostrado em um post anterior, sobre ângulos. Aqui usamos o raycast radial limitando o ângulo de visão do personagem, “imitando” o comportamento de uma laterna (WASD para mover e o mouse para mirar/atirar).

Caso não tenham percebido, não há colisão com as paredes pois não é a intenção desse post não é ensinar sobre colisão, mas fiquem a vontade para implentar. Outro ponto é que comecei a criar e usar um framework para desenhar no canvas do HTML5, segue aqui o link dele (com base no conhecimento dos outros tutoriais desenvolvidos). Caso tenham dúvidas ou sugestões sobre ele comentem, por favor (:
O projeto completo está, como sempre, no Github. Baixa lá, e fica como tarefa, criar um inimigo que vigie nosso personagem, e emite um alerta, caso entre no seu campo de visão.

Referencias:

Equações Paramétricas da Reta
2D Visibility

  • Pingback: Visibilidade 2D |()

  • Yuri Buenaga Holtz

    Parabéns! Não tem ideia de como isso me ajudou, muito obrigado e, continue com as postagens!

  • Diego R. Santos

    Realmente, ótima qualidade dos posts, por favor continuem rs, esses exemplos dinâmicos ajudam demais! Parabéns!