Cidade em uma Garrafa – sistema de raycasting de 256 bytes
(frankforce.com)City In A Bottle – sistema de raycasting de 256 bytes
-
Introdução
- Hoje vamos apresentar um pequeno motor de raycasting e um gerador de cidades contidos em um arquivo HTML de 256 bytes.
- É possível entender este programa como se estivesse resolvendo um quebra-cabeça que condensa vários conceitos em um espaço minúsculo.
- Os principais componentes são o código HTML, o loop de atualização de frames, o sistema de renderização, o motor de raycasting e a própria cidade.
-
Código completo
- Este código não é apenas um snippet simples de JavaScript, mas sim um programa HTML completo.
-
<canvas style=width:99% id=c onclick=setInterval('for(c.width=w=99,++t,i=6e3;i--;c.getContext`2d`.fillRect(i%w,i/w|0,1-d*Z/w+s,1))for(a=i%w/50-1,s=b=1-i/4e3,X=t,Y=Z=d=1;++Z<w&(Y<6-(32<Z&27<X%w&&X/9^Z/8)*8%46||d|(s=(X&Y&Z)%3/Z,a=b=1,d=Z/w));Y-=b)X+=a',t=9)>
Código HTML
- Código HTML
- A parte em HTML é composta por um elemento canvas simples e um evento
onclick. -
<canvas style=width:99% id=c onclick=setInterval('',t=9)> - O id do elemento canvas é definido como
c, permitindo acesso via JavaScript. - O evento
onclickinicia o programa e cria o loop de atualização por meio da chamada asetInterval.
- A parte em HTML é composta por um elemento canvas simples e um evento
Código JavaScript
-
Código JavaScript
- Código JavaScript de 199 bytes executado quando o canvas é clicado.
-
for(c.width=w=99,++t,i=6e3;i--;c.getContext`2d`.fillRect(i%w,i/w|0,1-d*Z/w+s,1))for(a=i%w/50-1,s=b=1-i/4e3,X=t,Y=Z=d=1;++Z<w&(Y<6-(32<Z&27<X%w&&X/9^Z/8)*8%46||d|(s=(X&Y&Z)%3/Z,a=b=1,d=Z/w));Y-=b)X+=a
-
Análise do código
- O código foi decomposto para facilitar a leitura.
-
c.width = w = 99 ++t for (i = 6e3; i--;){ a = i%w/50 - 1 s = b = 1 - i/4e3 X = t Y = Z = d = 1 for(; ++Z<w & (Y < 6 - (32<Z & 27<X%w && X/9^Z/8)*8%46 || d | (s = (X&Y&Z)%3/Z, a = b = 1, d = Z/w));) { X += a Y -= b } c.getContext`2d`.fillRect(i%w, i/w|0, 1 - d*Z/w + s, 1) }
-
Explicação passo a passo do código
c.width = w = 99: inicializa o canvas e define sua largura como 99 pixels.++t: incrementa a variável de tempo para criar a animação.for (i = 6e3; i--;){}: usa um loop para determinar o brilho de cada pixel.a = i % w / 50 - 1: calcula o componente horizontal do vetor da câmera.b = s = 1 - i / 4e3: calcula o componente vertical do vetor da câmera.X = t: usa o valor do tempo como posição X inicial.Y = Z = d = 1: inicializa os valores de Y, Z e d.for(; ++Z<w & ...;): o sistema de raycasting continua em loop até detectar uma colisão.c.getContext2d.fillRect(i%w, i/w|0, 1 - d*Z/w + s, 1): desenha cada pixel para formar a imagem final.
Aprendizado adicional
- Aprendizado adicional
- Este demo foi apresentado na demoparty Revision 2022 e pode ser conferido no Pouet.
- Também é possível ver uma versão expandida para um shader de 256 bytes no Shadertoy.
- Uma ferramenta interativa criada por Daniel Darabos permite manipular em tempo real vários aspectos do programa.
Opinião do GN⁺
-
Pontos interessantes
- Este programa mostra como gerar gráficos complexos com uma quantidade extremamente pequena de código.
- Usa apenas matemática básica, o que o torna compreensível até para engenheiros de software iniciantes.
- É um bom exemplo de otimização de código e minimalismo, podendo ser útil em competições como code golf.
-
Visão crítica
- Como o código é extremamente comprimido, a legibilidade pode ser prejudicada.
- Ele é mais adequado para fins artísticos e experimentais do que para aplicações práticas.
-
Tecnologias relacionadas
- Em projetos semelhantes, é possível encontrar diversos exemplos de shaders no Shadertoy.
- Também dá para explorar outros exemplos de código curto em plataformas como o Dwitter.
-
Considerações para adoção da tecnologia
- Ao adotar essa técnica, é preciso considerar a legibilidade e a manutenibilidade do código.
- Também é importante reconhecer as dificuldades de otimização de desempenho e depuração ao implementar funcionalidades complexas com pouco código.
1 comentários
Opiniões no Hacker News
Resumo da coletânea de comentários do Hacker News
Jogo de Pinball de 1K em JavaScript:
Geração procedural e avaliação preguiçosa:
Outras opiniões: