Ciudad en una botella – sistema de raycasting de 256 bytes
(frankforce.com)City In A Bottle – sistema de raycasting de 256 bytes
-
Introducción
- Hoy presentamos un pequeño motor de raycasting y generador de ciudades contenido en un archivo HTML de 256 bytes.
- Este programa reúne varios conceptos en un espacio diminuto y puede entenderse como si se resolviera un rompecabezas.
- Sus componentes principales son el código HTML, el bucle de actualización de frames, el sistema de renderizado, el motor de raycasting y la propia ciudad.
-
Código completo
- Este código no es un simple snippet de JavaScript, sino un 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
- La parte HTML está compuesta por un elemento canvas sencillo y un evento onclick.
-
<canvas style=width:99% id=c onclick=setInterval('',t=9)> - El id del elemento canvas está configurado como
c, para poder acceder a él desde JavaScript. - El evento onclick inicia el programa y crea el bucle de actualización mediante una llamada a setInterval.
Código JavaScript
-
Código JavaScript
- Código JavaScript de 199 bytes que se ejecuta cuando se hace clic en el canvas.
-
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álisis del código
- Se descompone el código para facilitar su lectura.
-
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) }
-
Explicación del código paso a paso
c.width = w = 99: inicializa el canvas y establece el ancho en 99 píxeles.++t: incrementa la variable de tiempo para crear la animación.for (i = 6e3; i--;){}: determina el brillo de cada píxel a través de un bucle.a = i % w / 50 - 1: calcula el componente horizontal del vector de cámara.b = s = 1 - i / 4e3: calcula el componente vertical del vector de cámara.X = t: usa el valor del tiempo como posición inicial en X.Y = Z = d = 1: inicializa los valores Y, Z y d.for(; ++Z<w & ...;): el sistema de raycasting itera hasta detectar una colisión.c.getContext2d.fillRect(i%w, i/w|0, 1 - d*Z/w + s, 1): dibuja cada píxel para formar la imagen final.
Aprendizaje adicional
- Aprendizaje adicional
- Este demo fue presentado en la demoparty Revision 2022 y puede verse en Pouet.
- También se puede encontrar una versión ampliada como shader de 256 bytes en Shadertoy.
- Mediante una herramienta interactiva creada por Daniel Darabos, es posible manipular en tiempo real distintos aspectos del programa.
Opinión de GN⁺
-
Puntos interesantes
- Este programa muestra cómo generar gráficos complejos con código extremadamente pequeño.
- Solo utiliza matemáticas básicas, fáciles de entender incluso para ingenieros de software principiantes.
- Es un buen ejemplo de optimización de código y minimalismo, y puede ser útil en competencias como code golf.
-
Visión crítica
- El código está tan comprimido que su legibilidad puede verse afectada.
- Es más adecuado para fines artísticos y experimentales que para aplicaciones prácticas.
-
Tecnologías relacionadas
- En proyectos similares, se pueden revisar diversos ejemplos de shaders en Shadertoy.
- También se pueden explorar otros ejemplos de código pequeño en plataformas como Dwitter.
-
Consideraciones para adoptar la tecnología
- Al adoptar esta técnica, hay que considerar la legibilidad y mantenibilidad del código.
- También hay que tener en cuenta las dificultades de optimización de rendimiento y depuración que implica implementar funciones complejas con código muy pequeño.
1 comentarios
Comentarios en Hacker News
Resumen de comentarios de Hacker News
1K Pinball Game in JavaScript:
Generación procedural y evaluación perezosa:
Otros comentarios: