
Bom tempo, comunidade Habr.
Muitos anos atrás, me deparei com um post
(1) . Fiquei intrigado com a oportunidade de criar elementos interessantes para a jogabilidade em roguelike
(2) . Suponha que um adversário possa estar atrás de um muro, e não o veremos até que o encontremos na linha de visão. Mas prefiro a situação em que, viajando pelos corredores da masmorra, revelamos as características da localização dos objetos gradualmente com base na área de visibilidade.
Posteriormente nas postagens:
(3) ,
(4) e
(5) , foram consideradas as questões do lançamento de sombras em jogos 2D. Como observado pelos próprios autores e nos comentários, o cálculo das sombras é bastante volumoso e não é uma tarefa fácil, tanto para a calculadora quanto para o design.
De alguma forma, tive alguns dias livres e decidi voltar à questão de sombras mais promissoras. É claro que a placa de vídeo lida com as sombras com sucesso e rapidez, mas nesse caso, eu queria processar as sombras para um jogo em 2D e parecia supérfluo transferir os cálculos para a placa de vídeo. Sim, e a potência do processador nos últimos anos como um todo aumentou, na verdade, um post sobre o que aconteceu no final.
O programa foi escrito em Pascal, simplesmente porque eu o conheço bem, e o Lazarus é um IDE aberto com uma ampla variedade de componentes.
A idéia original era desenhar linhas, do observador através de cada um dos cantos do ladrilho, e depois escurecer a figura resultante.

No entanto, essa sombra parece pouco natural quando o ângulo de visão muda. As sombras agora são mais amplas, agora mais estreitas.

A sombra de um objeto redondo parece muito melhor. Para criar essa sombra, você precisa desenhar duas tangentes do ponto de observação ao círculo e às bordas da tela. O diâmetro do círculo corresponderá ao tamanho do bloco.
No meu programa, usei a seguinte função:
Onde (x1, y1) é o ponto de observação, (x2, y2) é o centro do círculo, ® é seu raio e (x3, y3) e (x4, y4) são os pontos de interseção das linhas e do círculo. A função retorna true somente quando o observador está fora do círculo.
Como o processador não é muito amigável com trigonometria, tentei usá-lo no mínimo. Na verdade, com base em uma regra simples (modelo aproximado), os especialistas lhe dirão o porquê.
(Ruim) SIN, COS ..> '/', SQRT> 'DIV', 'MOD'> 'SHR', 'SHL'> '*'> ': =', '+', '-', 'AND ',' XOR '.. (Bom)É um prazer implementar a parte gráfica das primitivas na tela, existem muitas bibliotecas e mecanismos que facilitam o trabalho. Ao desenvolver no Delphi, tive que usar a biblioteca Agg2D, no Lazarus existe a sua porta
(6) , e decidi realizar a idéia. Na verdade, o ganho da biblioteca é que um canal alfa é adicionado às cores RGB e as primitivas são suavizadas e, devido ao acesso direto a pixels e vários truques, o processamento é muito mais rápido que a tela.
Ao desenhar a sombra do ladrilho, originalmente eu preenchia o setor com sombra, mas a imagem dentro do ladrilho era pouco distinguível (o setor em questão na Figura 3. é preenchido com verde). Tendo experimentado várias opções, parei de selecionar um setor na área de sombras.
Para desenhar o setor, precisamos de um ângulo em radianos, mas a trigonometria ainda não poderia. (arctan2 - função da biblioteca de módulos matemáticos)
Na verdade, tudo está pronto para a montagem da imagem. Tomamos um mapa de peças e, em uma camada separada, aplicamos sombras seqüencialmente, uma a uma. Para árvores, as sombras são mais escuras, para outros objetos, as sombras são mais transparentes.

A imagem final é aplicada sobre a camada principal de ladrilhos. Um pouco de design de plano de fundo e escolha conjuntos de peças mais genéricos. Na verdade, levei dois dias para procurar conjuntos de peças apropriadas, aquelas que são de domínio público ou de qualidade ou custo muito baixos. Como resultado, ele mesmo desenhou as árvores e pegou outros elementos emprestados do usuário Joe Williamson
(7) (excelente estilo).

Tudo acabaria, mas havia algum sedimento sobre o desempenho. Com o número de objetos, começa cerca de quinhentos rebaixamentos. Vários métodos de otimização foram considerados, e, dividindo-se em kernels e restringindo a área de desenho a um determinado raio, alterando a forma da sombra (para um preço mais barato que os arcos), pensei em transferir o cálculo para o vídeo.
Como resultado, cheguei à conclusão de que a melhor opção seria reduzir a amostragem da imagem servindo como uma máscara de sombra. Como o número de cálculos é reduzido significativamente, bem como o efeito inesperado da pixelização dos contornos das sombras, o que dá um certo charme à moda antiga.

Gostei tanto do efeito que tive que tornar o dimensionamento um processo dinâmico, através de um determinado parâmetro de multiplicidade.

Tudo o que restou foi criar paredes opacas e apresentar o resultado à comunidade.

Estou ansioso para novos jogos usando esse efeito ou seu desenvolvimento.
Obrigada
Demonstração em que você pode tocar nas alças (exe para Windows).
Parte 2 ,
Parte 3Referências:1) habr.com/post/16927/
2) en.wikipedia.org/wiki/Roguelike
3) habr.com/post/204782/
4) habr.com/post/305252/
5) habr.com/post/319530/
6) wiki.freepascal.org/BGRABitmap
7) twitter.com/joecreates