Manual de programación del ZX Spectrum para (muy) torpes





CAPÍTULO 7: Programando un mini-juego con CharAde.

Sobre lo que vamos a programar en este capítulo, pues va a ser algo parecido a una versión cutre de un clásico de los juegos de plataformas spectrumeros, "La Pulga", aunque vamos a tomar como fuente de inspiración una "versión" amateur realizada en BASIC y que ya de por sí era cutrilla, así que no esperéis el juegazo del siglo, los augurios no son buenos. 
A la derecha podemos ver un pantallazo del juego original (esto es, el "remake"). Los sprites (por llamarlos de alguna manera) tienen un solo caracter de tamaño (8x8 píxeles) y el juego (por llamarlo de alguna manera) se limita a una única pantalla. Algunos pitidos por ahí componen la banda sonora. El enemigo, un bicho raro volador se lanza hacia nosotros en linea recta si no hay obstáculos, en caso contrario se queda bloqueado en el obstáculo. El salto de nuestro protagonista es igualmente en línea recta, las parabólicas son muy complicadas, es más fácil esto de aquí, que parece que nos hayamos montado en un cohete espacial cada vez que intentamos dar un salto, a todas luces. Hay pocos elementos más que debamos rescatar para entrar en caliente. Justo debajo de la pantalla, podemos apreciar los UDG que componen el pseudo-sprite, que ocupa tan solo un caracter (en el juego original y en su segunda parte oficial el sprite del personaje protagonista es de mayor tamaño).

Cosas que vamos a necesitar: un disco para +3, el engine gráfico CharAde (ver el párrafo más abajo) y aproximadamente dos toneladas de paciencia. Crearemos un programa para la intro del juego y otro para el juego en sí mismo. 
Necesitaremos pues algunas pantallas de fondo para la presentación y podemos usar un juego de caracteres más futurista, no afecta de manera importante.

Con respecto al CharAde, es un engine o motor gráfico para Sinclair BASIC lanzado en 2015 por el programador Jason J. Railton ("joefish"). Consiste en un bloque de CM de 11k que contiene toda una serie de nuevas funciones gráficas, a las que se accede simplemente a través de la orden LPRINT. El siguiente es un pequeño ejemplo que circula por los foros del WOS, un simple "Hello World":

 10 CLEAR 54099: LOAD "char_ade.bin" CODE : LET pk=USR 54100
 20 CLS
 30 LPRINT "\@C0Hello World)"
 40 PAUSE 0
 50 LPRINT "@55"
 60 LPRINT ".12.,8..3,7..4,.65."
 70 LPRINT ")"
 80 LPRINT "@5NH W,E O,L R,L L,O D)"
 90 PAUSE 0
100 LPRINT "!#2"
110 FOR N = 0 TO 17 : LPRINT "&" + CHR$(4+N) + CHR$(21-N) + "CHARADE" : NEXT N
120 LPRINT "()"
130 PAUSE 0
140 FOR N = 0 TO 31 : LPRINT ": " + CHR$(N) + "()" : NEXT N

La pantalla derecha superior presenta el resultado del programa de las líneas 30 a 80, mientras que la pantalla derecha inferior corresponde a las líneas 100-140. CharAde incluye tantas nuevas funciones y características que de hecho es un mini-lenguaje incrustado dentro del Sinclair BASIC. Para intentar hacerlo más claro, vamos a probar a presentar el mismo programa "Hello World" con otro formato, sacando el código BASIC:

"cls"                                 
\@C0Hello World)                      
"pause"                               
@55                                   
.12.,8..3,7..4,.65.                   
)                                     
@5NH W,E O,L R,L L,O D)               
"pause"                               
!#2                                   
"loop"                                
&" + CHR$(4+N) + CHR$(21-N) "CHARADE
"end_loop"                            
()                                    
"loop"                                
" + CHR$(N) + "()                   
"end_loop"                            

El código CharAde se nos hace aun un poco críptico, debido principalmente a que el formato consiste en "tokens" de una sola letra. Vamos a extender finalmente el meta-código con el nombre de cada función (o su descripción resumida), según el Manual de la herramienta, a todo el listado:

"cls"                                                     
    newline_upward                     \                  
    set_cursor_foreground(y,x)         @C0                
    'Hello World'                      Hello World        
    render_foreground                  )                  
"pause"                                                   
    set_cursor_foreground(y,x)         @55                
    .'12'.,'8'..'3','7'..'4',.'65'.    .12.,8..3,7..4,.65.
    render_foreground                  )                  
    set_cursor_foreground(y,x)         @5N                
    'H W','E O','L R','L L','O D'      H W,E O,L R,L L,O D
    render_foreground                  )                  
"pause"                                                   
    clear_screens                      !                  
    load_character_set(n)              #2                 
"loop"                                                    
    set_cursor_background(y,x)         &[]                
    'CHARADE'                          CHARADE            
"end_loop"                                                
    copy_back_to_foreground            (                  
    render_foreground                  )                  
"loop"                                                    
    offset_background_relative(y,x)    :[]                
    copy_back_to_foreground            (                  
    render_foreground                  )                  
"end_loop"                                                
 
Ahora por fin está un poco más claro el funcionamiento de la demo y la lógica del listado. Como se puede apreciar, no hay instrucciones con respecto al color, pese a lo cual los caracteres que hemos impreso sí muestran color en pantalla. Esto es debido a que los caracteres son definidos, color incluido, a través de un editor incorporado en el programa, permitiendo el engine cambiar entre 4 diferentes charsets de 64 caracteres. En este caso, el juego de caracteres que viene por defecto con el programa tiene editados los números en cyan, las mayúsculas en amarillo y las minúsculas en blanco. También se puede observar que el fondo de pantalla mostrado por defecto es negro, y no cubre toda la pantalla, sino solo una ventana de 24x18 caracteres (192x144 píxeles), que es con la que trabaja CharAde, centrada en la pantalla y dejando un margen de 2 caracteres (16 píxeles) hasta el borde en su parte superior, y de 4 caracteres (32 píxeles) para los lados y la parte inferior. El manual sugiere emplear este espacio externo a la ventana para marcadores, puntuación y decoración gráfica diversa.

Lo siguiente que necesitamos es entender un poco el funcionamiento interno del motor gráfico, para lo que recurriremos de nuevo a los textos del Manual del usuario. Dos de los elementos fundamentales de este programa son dos áreas de pantalla (no visibles) de 32x32 caracteres, referidas en el Manual como Foreground Screen y Background Screen, a (y de) las cuales podemos copiar a gran velocidad información de (y a) la ventana de la pantalla estándar (24x18 caracteres).

Para seguir adelante, y como en los capítulos previos, antes que nada vamos a meter en un fichero DSK los archivos necesarios desde las imágenes de cassette originales en las que vienen distribuidos el engine, el editor de gráficos y varias demos. En el disco, el fichero del editor será llamado "cha_edit.bas", el del programa será llamado "char_ade.bin", con CODE 54100,11049. Este binario solo necesita ser llamado una vez. Emplearemos unas líneas como estas al principio de nuestro código fuente:
   1 CLEAR 54099                        | Nueva RAMTOP
   2 LOAD "char_ade.bin" CODE 54100     | El fichero mide 11049 bytes
   3 LET pk=USR 54100                   | Llamada y activación del
                                        | binario
Una vez ejecutado el USR 54100, el contenido de los comandos LPRINT es dirigido al (y ejecutado por el) engine.

Para ilustrar la manera en la que opera todo esto, démosle un vistazo al listado de la derecha, correspondiente como el primero a una demo del CharAde (en el disco, fichero "spiker.bas", autoejecución con LINE 9990). Los colores marcan (azul) los puntos de entrada de los saltos, (amarillo) los puntos de salida de los saltos y (rojo) las llamadas a la rutina gráfica a través de LPRINT, las consultas con PEEK (pk), también documentadas en el Manual, y el contenido de las variables y matrices que se le pasan como argumentos a LPRINT.

La estructura de este programa está dividida básicamente en dos bloques:
  • Líneas 1000-1120: inicialización y presentación (1000-1030), declaración de variables (1080-1090, 1110) y carga de los datos en matrices (1100,1120). La matriz p$ contiene los gráficos de la nave. En esta primera parte el engine solo es usado en las líneas 1010-1030.
  • Líneas 50-160: bucle principal de la demo; consulta las variables del engine mediante PEEK (pk) en las líneas 60-80 y 100, prescindiendo de la función INKEY$ para leer el teclado. Con las líneas 120 a 160 se actualiza la pantalla y retorna al principio del bucle.
Con esta demo obtenemos un scroll horizontal unidireccional (de izquierda a derecha) con animación carácter a carácter (8x8 píxeles). La presentación es más que aceptable, por no decir simplemente increíble si no perdemos de vista que no hemos salido del intérprete de BASIC. 

ċ
Char_Ade.dsk.zip
(271k)
Rambo Petazeta,
7 jul. 2018 14:42
ċ
charade_demo.rar
(43k)
Rambo Petazeta,
30 dic. 2018 6:13
ċ
pancho.rar
(322k)
Rambo Petazeta,
23 feb. 2019 3:07
Comments