Gracias gente! Pero vamos que hasta ahora lo único que he hecho es transcribir código, y optimizar tramos o circunvalar errores
En este momento la única ventaja que tiene este engine por sobre la extensión raycasting es que cada columna se puede maniobrar de forma individual; dando lugar a efectos psicodélicos en el render como por ejemplo
cambiar el ángulo de los actives de las paredes para dar un efecto de "aplastamiento", y cosas más simples como alterar el FOV del jugador (basta tan solo con alterar el vector de Plane para cambiar la forma del campo de visión).
Y si ya con definicion /2 va a 60FPS en una PC convencional entonces 2 puede llegar a ser la definición ideal por ahora
Queda considerar que si alguien va a trabajar sobre este motor, es altamente recomendable que hagan el hud a los laterales de la pantalla, en lugar de hacerlo abajo de la pantalla porque de esta forma
se pueden ahorrar de dibujar unas cuantas columnas, acelerando el proceso de renderizado; cosa que no ocurre si el hud cubre la parte inferior de la pantalla.
Ah, y por ahora el tema de renderizar el piso lo voy a dejar como un tema aparte.
Es bastante más exhaustivo renderizar un piso que renderizar las paredes porque
tengo que hacer cálculos píxel por pixel. Esto implicaría agregar un bucle más al cálculo, que podría tomar entre 0 y 100 pasos extra, dependiendo de la cantidad de piso que hay que dibujar en cada columna, y de todas formas necesitaría sí o sí de una extensión para propiamente dibujar el piso; así que no vale la pena
.
Y esto ocurriría igual aunque use pisos planos, ya que de todas formas tengo que ver "hasta donde va un color, y hasta donde va otro" y cosas así.
Una solución sería usar un "piso fake" haciendo que solo hayan sprites en el piso, en una onda "efecto piedritas", que se muevan con el mapa para dar una ilusion de piso. Pero para esto tengo que hacer que el engine pueda colocar sprites; que sin sprites, lo único que se puede hacer con esto es un "laberinto 3D", vacío, nada más
Mini-update, acabo de agregar algunas texturas de 64x64 de wolfenstein 3D, just because
[Tienes que estar registrado y conectado para ver esa imagen]El unico trabajo de hoy fué inventarme un script de ImageMagick (Es algo asi como un sistema que se basa en comandos para poder, por ejemplo, editar imágenes en forma masiva mediante scripts) para "trozear" una textura de 64x64 (imagen.bmp) y convertirla en 64 archivos separados de 1x64 (a_0.bmp hasta a_63.bmp); para así poder importarlos fácilmente en MMF2.
Esto va a parar a un archivo trozear.bat, en la misma carpeta que el imagemagick
- Código:
-
@echo off
for /l %%x in (0, 1, 64) do (
convert .\imagen.bmp -crop 1x64+%%x+0 .\a_%%x.bmp
echo %%x
)
echo Listo!
pause
Luego es solo cuestión de importarlas en el MMF2 como animación, y cambiarles el hotspot al centro (Para correr todos los hotspots de la animación al mismo tiempo es
Alt+[Tienes que estar registrado y conectado para ver esa imagen]; si no fuera por eso tendría que ir 64 veces, por todos los frames, a corregir los hotspots manualmente x'D)
Ah, y también configuré el juego para que se renderizara de forma espejada en los ejes negativos.
Esencialmente lo único que hice fué cambiar de
[Tienes que estar registrado y conectado para ver esa imagen]a
[Tienes que estar registrado y conectado para ver esa imagen].
Y oh por dios, lo que se glitchea el mapa de ese lado es terrible x'DD
[Tienes que estar registrado y conectado para ver esa imagen]Notar como pinté de azul las paredes que están cerca de los ejes, a manera de ilustrar donde está ubicado el "borde" del nivel.
De todas formas no se detecta la colisión en esos lados y se pueden atravesar las paredes, lo que hace que todo se vea todavía más bizarro. (Salvo en el -1 de cada eje, donde SÍ se detecta colisión por usar valores truncados en la detección de colisión)
Parte de este error es causado porque la posición del jugador se "redondea mal", y acaba siendo 1 más que lo que debería ser en cada eje.
Por ejemplo (-2,1) se detecta como (-1,1). Y (6,-1) se detecta como (6,0); lo que explica
por qué hay colisión en el eje -1.
A causa de esto, debe haber alguna raíz negativa dando vueltas por ahí, o algún conflicto con la función módulo o alguna división por cero, o alguna cosa de esas. Pero en fin, esto una de las cosas que no voy a arreglar. Por ahora con tener todo un cuadrante disponible alcanza
Es muy curioso la forma en la que MMF2 considera las "excepciones matemáticas" cada vez que ocurren.
Por ejemplo, cualquier número dividido 0 tendría que dar "infinito", o en la mayoría de los casos, "fallar"; pero en MMF2 la respuesta a "fallar" es dar como resultado 0. Por lo tanto,
cualquier division por 0 dá como resultado 0.
Esto me sirvió para poder simplificar 4 condiciones que usaban On loop:
[Tienes que estar registrado y conectado para ver esa imagen]Notar como debo tener en cuenta los 6 casos paralelos (4 casos explícitos, que son RayDirX negativo/positivo y RayDirY negativo/positivo, y 2 casos implícitos que son RayDirX=0 y RayDirY=0) y debo pasar por 4 eventos extras de onloop para hacerlo (Que potencialmente ralentizan el código, ya que sabemos que MMF2 es considerablemente lento para las loops).
Pues nada, que como ?/0=0; pude inventarmen una "función signo" de la siguiente forma:
X/Abs(X)
X/Abs(X) = 1 si a>0
-1 si a<0
0 si a=0
Es medio complicado de explicar, pero viene a ser una suerte de
forma normal disyuntiva (creo que se llamaba así x'D) en la que se usa la función signo que coloqué allá arriba para determinar que valores se tomarán en la función.
Funciona más o menos de la misma forma que el
Inmediate IF Object, pero usando calculos matemáticos en vez de extensiones.
Es mas o menos esto:
En vez de hacer...
Si
condición=1, entonces Variable:=
valor1Si
condición=0, entonces Variable:=
valor2...se pasa a ser:
Always, Variable = (
valor1*condicion)
+ (
valor2*(1-
condicion))
En retrospectiva, usar una extensión sería más eficiente, pero rompería con el esquema de no usar extensiones
Eeeeeeen fin, mismo link de descarga, no hay mucho nuevo, ya vendría siendo hora que me ponga a averiguar cual sería la forma más eficiente de renderizar
sprites.
Se me había ocurrido usar un active por sprite (En vez de trozear el sprite en columnas como explica el tutorial) y valerme de la forma en la que MMF2 ordena los sprites para poder ordenar las paredes
según su altura en el render, y poder colocar los sprites en la "profundidad" correcta.
Aunque bien podría haber implementado un "salto", que no es más complicado que eso.
Habrá que verlo otro día