Tema 2 - Teclado y pantalla de texto
Sabemos escribir en pantalla y sabemos leer de teclado, pero todavía de forma muy rudimentaria:
- No sabemos borrar la pantalla, ni escribir en cualquier posición, ni cambiar el color del texto.
- El usuario puede introducir datos, pero a cambio... el programa se queda totalmente parado hasta que termina de teclearlos. Esto es algo inadmisible en la gran mayoría de juegos, por ejemplo, en los que la acción debe seguir, tanto si el usuario pulsa una tecla como si no lo hace
Por eso, dentro de este apartado veremos:
- 2.1 Borrando la pantalla
- 2.2 Modos de de pantalla
- 2.3 Escribir en cualquier punto de la pantalla
- 2.4 Cómo cambiar de color
- 2.5 Comprobar el teclado sin parar el programa
- 2.6 Un ejemplo de casi todo
- 2.7 Comprobación avanzada del teclado
- 2.8 El juego de caracteres del CPC
- 2.9 El borde de la pantalla. Parpadeos
- 2.10 Leer lo que hay escrito en pantalla
- 2.11 Segundo ejercicio propuesto
2.1 Borrando la pantalla
La orden para borrar la pantalla es CLS. Esta orden existe en la gran mayoría de dialectos del lenguaje Basic:
CLS
2.2 Modos de pantalla
Los CPC llegan más allá. No sólo podemos borrar la pantalla, sino que también podemos elegir distintos modos de pantalla, que nos permiten tener más o menos letras en pantalla, y más o menos colores.
La memoria de pantalla de un CPC es muy limitada (16 KB), así que si queremos tener muchos puntos en pantalla será a cambio de tener pocos colores, y si nos apetece usar muchos colores, la cantidad de puntos será menor y las imágenes serán menos nítidas.
Los CPC permitían tres modos de pantalla:
- Modo 0: 25 líneas de texto, con 20 caracteres cada una. En modo gráfico, esto suponía 160x200 puntos, con 16 colores simultáneos, a elegir entre una paleta de 27 colores.
- Modo 1: 25 líneas de 40 caracteres (320x200 puntos, con 4 colores, también a elegir entre 27).
- Modo 2: 25 líneas de 80 caracteres (640x200 puntos, con 2 colores).
Para cambiar de un modo a otro, se usa la orden MODE, seguida por el número de modo (más adelante veremos un ejemplo completo).
2.3 Escribir en cualquier punto de la pantalla
La orden para escribir en una cierta posición de la pantalla en Locomotive Basic es LOCATE, y tras ella se indica la columna (X) y la fila (Y), así:
LOCATE 30, 10: PRINT "hola"
2.4 Cómo cambiar de color
En el Basic de los CPC existe una orden para cambiar el color de texto (PEN) y otra para el color de fondo (PAPER). A continuación de cualquiera de estas órdenes se indica el número de color que se quiere usar, de 0 a 15 (en modo 0; si estamos en un modo de mayor resolución, tendremos menos colores disponibles: 0 a 3 en modo 1, 0 a 1 en modo 2):
PAPER 1: PEN 3: PRINT "hola"
Los valores predefinidos para cada uno de los colores son:
Modo 2:
0: Azul (paleta 1) | 1: Amarillo intenso (paleta 24) |
Modo 1:
0: Azul (paleta 1) | 1: Amarillo intenso (paleta 24) |
2: Cyan claro (paleta 20) | 3: Rojo claro (paleta 6) |
Modo 0:
0: Azul (paleta 1) | 1: Amarillo intenso (paleta 24) | 2: Cyan claro (paleta 20) | 3: Rojo claro (paleta 6) |
4: Blanco (paleta 26) | 5: Negro (paleta 0) | 6: Azul claro (paleta 2) | 7: Magenta claro (paleta 8) |
8: Cyan (paleta 10) | 9: Amarillo (paleta 12) | 10: Azul pálido (paleta 14) | 11: Rosa (paleta 16) |
12: Verde claro (paleta 18) | 13: Verde pálido (paleta 22) | 14: Parpadeo Azul/Amarillo | 15: Parpadeo azul cielo/Rosa |
Pero esos valores se pueden redefinir a partir de los 27 colores de la paleta:
0 - Negro (5) | 1 - Azul (0,14) | 2 - Azul claro (6) | 3 - Rojo | 4 - Magenta | 5 - Violeta | 6 - Rojo claro (3) | 7 - Púrpura | 8 - Magenta claro (7) |
9 - Verde | 10 - Cyan (8) | 11 - Azul cielo (15) | 12 - Amarillo (9) | 13 - Gris | 14 - Azul pálido (10) | 15 - Anaranjado | 16 - Rosa (11) | 17 - Magenta pálido |
18 - Verde claro (12) | 19 - Verde mar | 20 - Cyan claro (2) | 21 - Verde lima | 22 - Verde pálido (13) | 23 - Cyan pálido | 24 - Amarillo claro (1) | 25 - Amarillo pálido | 26 - Blanco (4) |
Para redefinir un color usamos INK pluma, color. Por ejemplo, podemos escribir con color amarillo pálido sobre fondo negro, así:
INK 1, 0: INK 2, 25: PAPER 1: PEN 2: PRINT "hola"
2.5 Comprobar el teclado sin parar el programa
Podemos comprobar si el usuario ha pulsado una tecla con INKEY$. La forma habitual de usarla es guardando en otra variable su valor: tecla$=INKEY$. Si el resultado es una cadena vacía (""), quiere decir que el usuario no ha pulsado ninguna tecla. Como primer ejemplo, podríamos para el programa hasta que el usuario pulse cualquier tecla con
10 a$=INKEY$: IF a$="" THEN GOTO 10
2.6 Un ejemplo de casi todo
Hemos visto varias cosas seguidas. Llega el momento de ponerlas en marcha. Usaremos los modos 0,1 y 2, escribiremos en distintas posiciones de la pantalla, con distintos colores, y según lo que pulse el usuario, tomaremos acciones distintas...
(Nota: este fuente está "indentado", con la intención de que sea más fácil de leer, y se muestra con la sintaxis realzada en colores, para ayudar a distinguir las órdenes de los textos y de los números o símbolos. Una vez introducido en el CPC, estos colores del fuente no serán visibles).
10 'Jugando con el modo texto...
20 MODE 0
30 'Primero probaremos los colores
40 FOR i = 1 TO 15
50 PEN i
60 LOCATE 10,i+1
70 PRINT "Usando color ";i
80 NEXT i
90 'Y esperamos una tecla
100 LOCATE 1,25
110 PRINT "Pulsa una tecla..."
120 tecla$ = INKEY$
130 IF tecla$ = "" THEN GOTO 120
140 'Ahora, 4 azules distintos en Modo 1
150 MODE 1
160 INK 0, 1: INK 1,2: INK 2, 11: INK 3,20
170 'Escribiremos espacios en blanco
180 FOR i = 1 TO 15
190 LOCATE i,i
200 FOR j = 0 TO 3
210 PAPER j
220 PRINT " ";
230 NEXT j
240 NEXT i
250 'Esperamos otra tecla
260 tecla$ = INKEY$
270 IF tecla$ = "" THEN GOTO 260
280 'Finalmente, texto animado en modo 2
290 MODE 2
300 INK 0,3: INK 1,21: PEN 1: PAPER 0
310 PRINT "Pulsa P para terminar"
320 FOR i = 1 TO 1000
330 LOCATE 10,10
340 'Una de cada 3 veces, escribo HOLA
350 IF i MOD 3 = 1 THEN PRINT "HOLA"
360 'Una de cada 3 veces, escribo HO
370 IF i MOD 3 = 2 THEN PRINT "HO "
380 'Una de cada 3 veces, nada
390 IF i MOD 3 = 0 THEN PRINT " "
400 ' Si pulsa tecla, termino
410 letra$ = INKEY$
420 IF letra$ = "p" THEN GOTO 460
430 ' Si no, una pausa
440 FOR j = 1 TO 500: NEXT j
450 NEXT i
460 END
Todo debería ser fácil de seguir. Algunas de las cosas se podrían hacer de forma más elegante... usando órdenes que aún no conocemos, pero ya habrá tiempo para eso.
2.7 Comprobación avanzada del teclado
Puede haber ocasiones en que queramos comprobar si una tecla se ha pulsado a la vez que Mayúsculas o Ctrl, o queramos leer una tecla que no corresponda a ningún carácter concreto. Para esos tipos de comprobaciones más avanzadas, podemos usar la función INKEY, a la que le indicaremos el código de la tecla que queremos comprobar, según esta tabla:
(El dibujo muestra el teclado de un CPC664; los cambios para un 464 o un 6128 deberían ser mínimos). Por ejemplo, podemos ver si se ha pulsado la tecla COPY del CPC con:
IF INKEY(9) <> -1 THEN PRINT "COPY Pulsado"
Pero el programa no se para a esperar, igual que ocurre con INKEY$. Los valores que devuelve INKEY son: -1 (tecla no pulsada), 0 (tecla pulsada sola), 32 (tecla pulsada junto con Mayúsculas), 128 (tecla pulsada junto con Ctrl), 160 (tecla pulsada junto con Mayúsculas y Ctrl).
Un último comentario: INKEY no vacía el buffer del teclado. Si hacemos un programa que se quede parado hasta pulsar la tecla COPY (o cualquier otra), y luego usamos INPUT FRASE$, todas las teclas que hayamos pulsado anteriormente seguirán ahí, pendientes de ser analizadas, y serán parte de la variables FRASE$. Si queremos evitar este comportamiento, deberemos usar CLEAR INPUT, que sí vacía el buffer del teclado:
10 PRINT "Pulsa varias teclas y COPY"
20 IF INKEY(9) = -1 THEN GOTO 20
30 PRINT "COPY Pulsado. Escribe algo: ";
40 INPUT frase$
50 PRINT "Has tecleado: "; frase$
60 PRINT "Ahora vaciaremos el buffer:"
70 PRINT "Pulsa otras teclas y COPY"
80 IF INKEY(9) = -1 THEN GOTO 80
90 PRINT "COPY Pulsado. Escribe algo mas: ";
100 CLEAR INPUT
110 INPUT frase$
120 PRINT "Has tecleado: "; frase$
2.8 El juego de caracteres del CPC
El juego de caracteres del Amstrad CPC incluía todos los caracteres alfabéticos, numéricos y símbolos de puntuación del estándar ASCII, junto con una serie de caracteres semigráficos que permitían dibujar con facilidad recuadros, letras griegos y algunos otros caracteres especiales. Podemos mostrarlos a partir de su código ASCII, usando la función CHR$, como muestra este programa:
10 CLS
20 PRINT " 1 2"
30 FOR i=32 TO 255
40 PRINT CHR$(i);
50 IF (i-32) MOD 30 = 0 THEN PRINT: PRINT USING "### ";i+1;
60 NEXT i
70 PRINT:PRINT
80 PRINT " 1 2"
El paso contrario se puede dar con la función ASC: saber el número dentro del código ASCII que corresponde a un cierto carácter: PRINT ASC("a")
2.9 El borde de la pantalla. Parpadeos
En los laterales de la pantalla del CPC hay una zona en la que no podemos escribir, pero cuyo color podemos cambiar. Esto se consigue con la orden BORDER, indicando el color (0 a 26):
BORDER 21
También existe la opción de que el borde alterne entre dos colores distintos:
BORDER 21, 22
Además podemos ajustar la velocidad de ese parpadeo, o más exactamente, la cantidad de tiempo que será visible cada uno de esos colores, con SPEED INK:
SPEED INK 25, 10
Los números anteriores son cincuentavos de segundo (0,02s), luego estamos diciendo que el primer color sea visible durante medio segundo y el segundo durante 20 centésimas de segundo.
Si queremos que no sea el borde lo que parpadee, sino un texto, también lo podemos conseguir, modificando uno de los colores de nuestra paleta para que alterne entre dos colores distintos:
INK 2, 21, 22: PEN 2: PRINT "Hola"
En este ejemplo, escribiríamos un texto con el tercer color de nuestra paleta (2), que alternaría entre el verde lima (21) y el verde pálido (22), a la velocidad que le hayamos indicado con SPEED INK.
2.10 Leer lo que hay escrito en pantalla
Una curiosidad que en algún momento puntual puede resultar útil: podemos saber qué carácter hay en una posición concreta de la pantalla. El primer paso es movernos a esa posición con LOCATE. El segundo será leer con COPYCHR$, así:
LOCATE 10,3
letra$ = COPYCHR$(#0)
Eso de (#0) indica el "canal" desde el que queremos leer. Es un detalle en el que no profundizaremos por ahora, pero algunas órdenes permite que se le indica un canal y unas pocas (como COPYCHR$) lo exigen. Por ahora nos basta con saber que el canal 0 es la pantalla.
Dos órdenes relacionadas son POS, que nos dice la coordenada horizontal de la posición actual del cursor, y VPOS, que nos indica la coordenada vertical. Ambas necesitan también que se les indique el canal (de momento, #0, para referirnos a la pantalla.
LOCATE 11,5
posX = POS(#0): posY = VPOS(#0)
Nota: esta orden sólo existe en los CPC664 y superiores, no en los 4xx, en los que habría que imitarla usando código máquina.
2.11 Segundo ejercicio propuesto
Dibujar un rectángulo en el borde de la pantalla (por ejemplo, con el rectángulo relleno, carácter 143, o con el rectángulo de trama gruesa, carácter 206) y algún obstáculo en puntos intermedios de la pantalla (por ejemplo, con el rectángulo tramado fino, carácter 207). En el centro de la pantalla habrá un personaje (carácter 248). Cada vez que se pulse una flecha en el teclado, el personaje deberá moverse en la dirección indicada. Cuando el personaje se mueva cambiará de forma (por ejemplo, al carácter 250). Terminará cuando el personaje choque con un obstáculo o con el borde, o si se pulsa la tecla ESC.
La apariencia podría ser como ésta:
Y cuando el personaje choque, se podría imitar una explosión con el carácter 238, por ejemplo:
Si ya has intentado resolverlo ;-), puedes ver una propuesta de solución