Tutorial de ZX Basic + Fourspriter #9: Creando un tileset
22 febrero, 2012 2 comentarios
Un tileset no es más que un conjunto de gráficos que se usarán para pintar pantallas basadas en tiles, y que diseñaremos con el Mappy. Usaremos tiles de 16×16, por ejemplo. En nuestro caso, cada tile no sería más que cuatro UDG y sus respectivos colores, colocados dos encima de otros dos.
Ahora mismo no hay ninguna herramienta que yo sepa que sea capaz de autogenerarte el tileset. Hay subterfugios, como en la churrera: como solo hay 16 tiles, podemos permitirnos generar el tileset automáticamente. El tile N estará formado por los caracteres N*4, N*4+1, N*4+2 y N*4+3, y listo. Hay caracteres de sobra para tan pocos tiles, y podemos hacer esa burrez. Pero con solo 21 UDG, o si queremos tener muchos tiles (como en el Severin Sewers) no hay más narices que ponernos a crear los tiles a mano para aprovechar bien los caracteres disponibles.
Es muy fácil. Un tile no será más que una ristra de 8 bytes: 1 byte de color y 1 byte con el UDG correspondiente para cada una de las cuatro casillas. Así de simple.
Para montárnoslo, lo más fácil es empezar diseñando el tileset en nuestro editor gráfico favorito, repegando UDG y dándoles color. Esto, además, nos servirá para luego usarlo como tileset en el Mappy para hacer el mapa. Cuando los tengamos, con paciencia, haremos a manubrio nuestro array de tiles.
Empezaremos con un tileset sencillo de pocos tiles empleando los UDG del ejemplo anterior. Voy a hacer 16 tiles, paso de hacer más, pero en teoría sería factible hacer hasta 256. El primero, para estar a bien con Mappy, será el tile vacío negro feo. Lo llamaremos tileset-mappy.png y lo grabaremos en /gfx. Más que nada porque lo usaremos con el Mappy, además de como guía.
Ahora nos armamos de paciencia para empezar un archivo tileset.bas. Como tenemos 16 tiles, crearemos un array de dos dimensiones: 16 tiles de 8 bytes:
'' tileset.bas Dim tileset (15, 7) As uByte => { _
Sí, 15 y 7 en vez de 16 y 8. BASIC es así. Se indica el valor del último índice (se empieza en 0), y no el tamaño del Array. Sí, es un lío de cojones. Pero hay que joderse.
Pues nada, empezaremos con el primero. Se trata de cuatro espacios en blanco. Bueno, en negro. El ASCII del espacio es 32. Para ponerlos negros, usaremos PAPER 0, INK 0. El atributo se calcula como INK + 8 * PAPER + 64 * BRIGHT. Por tanto, 0 + 8*0 + 64*0 = 0. Así, vamos intercalando color y ASCII para los cuatro caracteres que forman el primer tile:
{0, 32, 0, 32, 0, 32, 0, 32}, _
Ea, ya tenemos el primero. Ánimo, solo quedan 15 más. Veamos, el siguiente es el de los ladrillicos cyan. Este es sencillo: los cuatro carácteres son el primer UDG. O sea, el ASCII 144. Para no liarte, puedes imprimir el set de UDG y escribir los numeritos de 144 a 164 debajo con boli, eso te ayuda:
Tres de los caracteres son de color cyan (5), menos el de la esquina que tiene BRIGHT, o sea 5 + 64 = 69. El segundo tile nos quedaría, por tanto:
{69, 144, 5, 144, 5, 144, 5, 144}, _
¡Yuju! Ahora quedan 14. Vamos a por el próximo. El segundo usa, alternados, los UDG tercero y cuarto, o sea, el 146 y el 147, alternando también sus colores entre rojo intenso (2 + 64 = 66) y rojo (2). Pues al lío:
{66, 146, 2, 147, 2, 147, 66, 146}, _
Venga, otro más. Este es de los fáciles: solo usa el quinto UDG: el 148. Los dos de arriba, amarillo intenso (6 + 64 = 70), los dos de abajo, amarillo normal (6):
{70, 148, 70, 148, 6, 148, 6, 148}, _
El siguiente es el de la seta, que usa cuatro UDGs diferentes: 149, 150, 151 y 152. Los dos de arriba, rojo intenso (2 + 64 = 66). Abajo amarillo intenso (70) y amarillo (6):
{66, 149, 66, 150, 70, 151, 6, 152}, _
Vamos acelerando… Los siguientes tres son muy sencillos:
{71, 154, 69, 154, 69, 154, 5, 154}, _ {68, 155, 68, 155, 4, 155, 4, 155}, _ {68, 156, 4, 156, 68, 156, 4, 156}, _
Luego dos más, los del cesped y la tierra, con los UDG 157 y 158 el primero y 159 el segundo. Luego el rosita (3 + 64 = 67) con el UDG 162:
{68, 157, 4, 157, 2, 158, 2, 158}, _ {66, 159, 66, 159, 66, 159, 66, 159}, _ {67, 162, 67, 162, 67, 162, 67, 162}, _
Para los dos siguientes, los del agua, usaremos PAPER 1, INK 7 y BRIGHT 1: 7 + 8 * 1 + 64 = 79. Ambos usan el carácter espacio, además del UDG 163:
{79, 163, 79, 163, 79, 32, 79, 32}, _ {79, 32, 79, 32, 79, 32, 79, 32}, _
Y para terminar (anda, que no ha sido para tanto), los tres tiles de hojitas que emplean el UDG número 164 con diferentes combinaciones de amarillos y verdes, además del espacio vacío (32) de color 0:
{70, 164, 68, 164, 0, 32, 68, 164}, _ {68, 164, 4, 164, 68, 164, 68, 164}, _ {4, 164, 0, 32, 4, 164, 4, 164} _ }
Para probarlos, vamos a crear un test2.bas que los imprima todos. Así matamos dos pájaros de un tiro: escribimos el código que pinta un tile en (x, y), y además vemos si nos hemos equivocado con los numericos.
'' test2.bas '' '' Nuestro segundo programa con Fourspriter. #include once "fsp2.1.bas" #include once "spriteset.bas" #include once "udg.bas" #include once "tileset.bas" '' Variables Dim i as uInteger '' Main Border 0: Paper 0: Ink 7: Cls Poke uInteger 23675, @udg (0) For i = 0 To 15 pintaTile (i * 2, 11, i) Next i End '' Subs Sub pintaTile (x as uByte, y as uInteger, n as uByte) Dim addr as uInteger addr = 22528 + x + (y << 5) Poke addr, tileset (n, 0): Poke addr + 1, tileset (n, 2) Poke addr + 32, tileset (n, 4): Poke addr + 33, tileset (n, 6) Print Paper 8; Ink 8; _ At y, x; Chr (tileset (n, 1)); Chr (tileset (n, 3)); _ At y + 1, x; Chr (tileset (n, 5)); Chr (tileset (n, 7)); End Sub
La función pintaTitle tiene un poco de hueva. Podéis usarla como caja negra, ya que en un futuro la estaré pasando a ensamblador, porque así, aunque está muy optimizada, es un poco lenta. Básicamente, los POKEs del principio ponen los colores en la memoria de video, y el PRINT de abajo pone los cuatro caracteres. Se usa PAPER 8 e INK 8 para que el PRINT no modifique los atributos que hemos puesto antes con los POKEs.
Compilamos test2.bas como siempre. Si todo ha ido bien, debería salir esto:
Pulsa aquí para descargar el paquetito con todo.
Después de este tutorial ya no hay excusa para los espectrumeros!
Hola! He detectao un «bixillo» en tus ejemplos 😀
Fijate que has puesto los atributos con bright (+64) y luego no hay ningún gráfico que imprima un atributo en bright en tus ejemplos…
La solución que he hecho yo? poner los atributos despues de los prints con los chars (y no hace falta entonces poner ink 8, paper 8)
Muchas gracias por tus tutoriales, son cojonudos! Que sepas que me están sirviendo mucho para pasar mis conceptos commodorianos al spectrum para hacer güegos.