Índice de entradas
Esta serie de artículos han sido traducidos a partir del documento "How to
Write ZX Spectrum Games" con permiso de su autor, Jonathan Cauldwell, un gran
desarrollador de juegos para el Spectrum, os recomiendo
visitar su Web donde está
el texto original. El documento original, y por tanto esta traducción, tiene
© Jonathan Cauldwell y solo puede duplicarse con permiso expreso por escrito
de su autor.
Gráficos de fondo
Presentando bloques
Digamos que queremos escribir un sencillo juego de laberinto por pantalla. Tenemos que mostrar
las paredes alrededor de las cuales el sprite del jugador debe ser movido, y la mejor
manera de hacer esto es crear una tabla de bloques que se transfieren a la pantalla
secuencialmente. A medida que avanzamos a través de la tabla encontramos la dirección del bloque
gráfico, cálculamos su dirección de pantalla y volcamos el carácter a la pantalla.
Vamos a empezar con la rutina de visualización de caracteres. A diferencia de la rutina que necesitamos para que el sprite
se acople a posiciones de caracteres, por suerte es más fácil calcular
una dirección de pantalla para una posición de carácter de lo que lo es para píxeles individuales.
Hay 24 posiciones de celdas de caracter verticales y 32 posiciones horizontales en la pantalla del spectrum,
por lo que nuestras coordenadas estarán entre (0,0) y (23,31). Las filas 0-7 caen en el primer segmento de pantalla, 8-15 en la sección media de la pantalla, y las posiciones 16-23 en la tercera parte de la pantalla. Tenemos suerte, el byte alto de la dirección de pantalla para cada segmento se incrementa en 8 de un segmento a otro, por lo que tomando el número de celdas verticales y realizando un and 24 inmediatamente obtenemos el desplazamiento del comienzo del segmento de pantalla que debemos abordar allí mismo.
Añadir 64 para el inicio de la pantalla del Spectrum y tenemos el byte alto de nuestra dirección. Entonces tenemos que encontrar la celda de carácter correcta dentro de cada segmento, por lo que tomamos de nuevo la coordenada vertical, y esta vez usamos and 7 para determinar cuál de las siete filas estamos tratando de encontrar. Multiplicamos esto por el ancho en caracteres de la pantalla (32) y añadimos el número de celda horizontal para encontrar el byte bajo de la dirección de la pantalla. Un ejemplo adecuado es el siguiente:
; retorna dirección de la celda de carácter en (b, c). chadd ld a,b ; posición vertical. and 24 ; ¿qué segmento, 0, 1 o 2? add a,64 ; 64*256 = 16384, memoria de pantalla del Spectrum. ld d,a ; este es nuestro byte alto. ld a,b ; ¿cuan es la posición vertical ahora? and 7 ; ¿qué fila dentro del segmento? rrca ; multiplcar fila por 32. rrca rrca ld e,a ; byte bajo. ld a,c ; añadir la coordenada y. add a,e ; mezclar con el byte bajo. ld e,a ; dirección de pantalla en de.
Una vez que tenemos nuestra dirección de pantalla es un proceso sencillo el volcar el
carácter a pantalla. Mientras que no estamos cruzando los límites de las celdas de caracteres
la siguiente línea de la pantalla siempre caerá 256 bytes después de la de su predecesor, por lo que
hay que incrementar el byte alto de dirección para encontrar la siguiente línea.
; Mostrar el caracter hl en (b, c). char call chadd ; encontrar la dirección en pantalla del caracter. ld b,8 ; numero del pixel alto. char0 ld a,(hl) ; fuente del grafico. ld (de),a ; transferir a la pantalla. inc hl ; siguiente trozo de datos. inc d ; siguiente linea de pixels. djnz char0 ; repetir ret
En cuanto a la coloración de nuestro bloque, lo hemos cubierto en el capítulo sobre
detección de colisiones de atributos sencilla. La rutina atadd nos dará la dirección de un atributo de
celda de carácter en (b, c).
Por último, tenemos que decidir qué bloque mostrar en cada celda de pantalla. Podemos pensar que
tenemos 3 tipos de bloques para nuestro juego, podríamos usar un bloque de tipo 0 para un espacio,
tipo 1 para el muro y tipo 2 para una puerta. Arreglaríamos los gráficos y atributos para
cada bloque en tablas separadas en el mismo orden:
blocks equ $ ; block 0 = caracter para espacio. defb 0,0,0,0,0,0,0,0 ; block 1 = muro. defb 1,1,1,255,16,16,16,255 ; block 2 = puerta. defb 6,9,9,14,16,32,80,32 attrs equ $ ; block 0 = espacio. defb 71 ; block 1 = muro. defb 22 ; block 2 = puerta. defb 70
A medida que avanzamos a través de nuestro tablero de hasta 24 filas y 32 columnas de bloques de laberinto cargamos el número del bloque en el acumulador, y llamamos a las rutinas fblock y fattr a continuación para obtener las direcciones del gráfico de origen y su atributo.
; Encontrar celda del gráfico. fblock rlca ; multiplicar el número de bloque por 8. rlca rlca ld e,a ; despalzar a la dirección del grafico. ld d,0 ; sin byte alto. ld hl,blocks ; dirección del bloque de caracteres. add hl,de ; apuntar al bloque. ret ; Encontrar celda de atributo. fattr ld e,a ; desplazamiento a la dirección del atributo. ld d,0 ; sin byte alto. ld hl,attrs ; dirección del bloque de atributos. add hl,de ; apuntar al bloque. ret
Usar este método significa que nuestros datos del laberinto requiere un byte de RAM por cada celda de carácter.
Para un área de juego de 32 celdas de ancho y 16 bloques de alto esto significaría
que cada pantalla ocupa 512 bytes de memoria. Eso estaría bien para 20 pantallas de
plataformas como en el Manic Miner, pero si quieres un centenar o más de pantallas deberías
considerar el uso de bloques más grandes de modo que requiera menos bloques cada pantalla. Mediante el uso
bloques de celdas de caracteres de 16 x 16 píxeles en lugar de los 8 x 8 en nuestro ejemplo,
cada tabla de pantalla requeriría sólo 128 bytes, lo que significa que podremos exprimir mas la memoria del Spectrum.
No hay comentarios:
Publicar un comentario