martes, 23 de octubre de 2007

Editando al Editor

Ha pasado bastante tiempo desde que escribí la última vez. En parte porque Reumatología me tuvo bastante ocupado hace unas semanas; y también porque escribir en este Blog es realmente mucho más rápido que avanzar en el juego. A pesar de todo, he trabajado bastante en el proyecto, y hoy publico los resultados.

En estricto rigor, del juego no he tocado ni una sola línea de código. Todos los esfuerzos están centrados, por ahora, en el editor de código. La última vez que hablé de esta herramienta, era aún una utilidad pequeña que mostraba sólo texto y tenía poca funcionalidad (aunque ese poco supuso un enorme aumento en la velocidad con que pude diseñar el nivel). De todas formas, el paso siguiente consistió en agregar nuevas funciones y obviamente, una interfaz visual más amigable.

El plan inicial era mostrar el nivel en plano, es decir, representar cada subunidad por una grilla que tuviera la textura correspondiente y algún número que mostrara la elevación. Mediante esta interfaz debería poderse modificar la textura a nivel de subunidad, y la elevación a nivel de vértice. Con esto, el editor se volvería muy fácil y rápido de usar. El problema que siempre llega después de la iluminación es "Ya está la idea, ¿pero ahora cómo la implememento?"

Recordando viejos tiempos

Algunos años atrás, hice un juego de fútbol en tablero, así como también un Battleship; en C Sharp, y ambos programas utilizaban una clase "Tablero Gráfico" genérica, que me sería sumamente útil para mis propósitos. Esa clase la creó un ayudante del curso, y era capaz de detectar los clicks, traducir las coordenadas en filas y columnas, marcar con colores las casillas, etc. Lo que yo necesitaba era algo parecido, pero con mayor funcionalidad, pues en vez de colores necesitaba texturas, además de discriminación entre vértice y área (para seleccionar la subunidad entera o sólo el vértice), y algunas cosas extras como capacidad de mostrar texto y lo que se me fuera ocurriendo en el camino. (Al momento de imaginar el programa me pongo a dibujar sobre un papel, y luego veo como implementarlo. Al momento de programar van cambiando las ideas y todo termina bastante distinto a como se planeó, es por eso que desde el inicio el diseño debe ser lo más flexible posible). Como ahora no trabajaba en C Sharp (Tanto el Avioncitos3D, como el editor de nivel están hechos en Visual Basic 6.0) no podía simplemente buscar la clase TableroGrafico y utilizarla. A lo más podría haberla leído y "traducido" a Visual Basic, pero al final, terminé decidiendo crear mi propia grilla desde cero, con las funcionalidades exactas que necesitara. Ahora bien, el C Sharp tiene funciones gráficas bastante más poderosas que las del Visual, ... La realidad es que las del Visual son horribles. Esto me dejaba sin la autosuficiencia del C Sharp para manejar los gráficos por sí solo, por tanto en mi caso debí buscar un "partner gráfico" para complementar al escueto Visual Basic.

Lo primero que pensé fue BitBlt... Es cierto que es bastante viejo, lento, etc. Pero se ve bastante bien para transferir los bitmaps de las texturas al formulario. De hecho, cuando imaginé el sistema, siempre tuve en mente a BitBlt para implementarlo.

Lo primero que hice fue leer sobre BitBlt de nuevo. Habían pasado muchos años desde que lo usé por última vez y me dediqué de lleno al DirectX. Cuando ya resfresqué la memoria, me di cuenta que no sería tan bueno como creía. El problema principal era que necesitaba copiar la imagen desde un Device Context, en el caso más simple un control Picture, pero nunca directamente desde un archivo. Al parecer la solución más simple sería usar DirectX7 y trabajar con Surfaces y BltFast, pero de esto no sabía mucho y no me agradaba la idea de mezclar tantas APIs en un solo proyecto. Al final me decidí por DirectX8, usando Transformed and Lit Vertices, tal como hice con el HUD en avioncitos.

Editando el Editor

Decidía crear mi grilla como una ventana de 8 por 8 subunidades, que se pudiera desplazar sobre el nivel y fuera mostrando información de elevación y textura de las 64 subunidades contenidas. Cuando dibujé los cuadros que representaríasn las subunidades, intenté hacerlo mediante TriangleStrips en vez de TriangleLists, lo que me ahorró muchos muchos vértices. Pensé que sería la solución ideal para rediseñar el Sistema de terreno del avioncitos (que usa 6 vértices por subunidad!!! una cantidad enorme, y se está quedando con frame rates muy muy pequeños). Sin embargo, al usar TriagleStrips surge el problema para mapear las texturas, que ya no podrían ser independientes, lo que atentaría contra la flexibilidad y realismo del juego. Por esta razón, decidí quedarme con los TriangleList y solucionar de otra forma (y en otro momento) el problema del Frame Rate.

Después de algunos días de trabajo (¿dos o tres?), el editor quedó con su "grilla de subunidades" operativa y una funcional adicional: Un previsualizador 3D del terreno. Usé la misma lógica del sistema de terreno del avioncitos y creé una ventana navegable que permite moverse por el terreno y visualizar en 3 dimensiones y de manera inmediata, los cambios hechos al archivo de terreno, incluso sin haber escrito aún en éste (Trabaja sobre una copia en la RAM, que sólo se graba al archivo en el disco cuando se está conforme con el resultado).

Hoy decidí subir algunos snapshots del Editor de terreno, que si bien no está totalmente funcional (Le faltan las herramientas para manejar texturas y más funcinalidad respecto a las elevaciones), de todas formas funciona y ya está siendo de utilidad para el diseño del juego.



La imagen anterior muestra la interfaz actual del editor, con la ventana de previsualización 3D a la derecha y el archivo de elevación en modo texto a la izquierda. La barra de menús permitió agregar comandos de edición ahorrando botones en la pantalla. En la vista 3D la cámara se puede mover libremente con los controles de posición.


Esta imagen muestra al editor en modo "diseño de texturas". En la ventana de la izquierda se encuentra representado en plano un trozo de la geometría, para así editar las texturas de cada subunidad. Nótese como las bandas blancas, en la visión plana, se corresponden con las que aparecen en el cerro visible en la previsualización 3D. La edición de los patrones de textura se refleja inmediatamente en la geometría 3D.


Este es un ejemplo de una operación que sin el editor sería muy complicada. Vamos a copiar el cerro indicado con la flecha y lo pegaremos en la ubicación de la marca blanca, de modo que ésta sirva como textura para tapizarlo. Para esta operación se recurre a la función Copiar/Insertar del menú Edición.


Aquí vemos el resultado de la operación: Una copia del cerro original (al fondo), que utiliza la textura de la marca blanca donde fue creado. Este patrón de texturas podrá editarse fácilmente en el modo de edición de texturas.

Esta es una muestra inicial de la evolución del editor, que pasó se ser una ventana simple con algunos botones; a una interfaz rica, con menús y vistas 3D. En el futuro pretendo mejorar la interfaz gráfica de edición de elevacion y texturas, para que crear terrenos llamativos se vuelva una tarea simple. ¡El proyecto sigue avanzando!