Manual de Basic Spectrum 48k.

Capítulo 18

Movimiento

Resumen

  • PAUSE, INKEY$, PEEK

Con bastante frecuencia, deseará conseguir que el programa tenga una duración determinada y para tal fin, encontrará de utilidad la sentencia PAUSE.

PAUSE n

interrumpe el cómputo y congela el contenido de pantalla durante n imágenes de la televisión (a 50 imágenes por segundo en Europa o 60 en América). El valor n puede ser de hasta 65535, lo que le proporciona poco menos de 22 minutos; si n = 0, entonces, significa "Pausa para siempre".

Una pausa siempre puede acortarse pulsando una tecla (tenga presente que un espacio con CAPS SHIFT producirá también una interrupción). Ha de pulsar la tecla después de que haya comenzado la pausa.

El siguiente programa actúa sobre el segundero de un reloj.

  10 REM Primero dibujamos el cuadrante del reloj
  20 FOR n = 1 TO 12
  30 PRINT AT 10 - 10 * COS (n / 6 * PI), 16 + 10 * SIN (n / 6 * Pl); n
  40 NEXT n
  50 REM Ahora ponemos en marcha el reloj
  60 FOR t = 0 TO 200000: REM t es el tiempo en segundos
  70 LET a = t / 30 * PI : REM a es el ángulo del segundero en radianes
  80 LET sx = 80 * SIN a: LET sy = 80 * COS a
200 PLOT 128, 88: DRAW OVER 1; sx, sy: REM dibujo del segundero
210 PAUSE 42
220 PLOT 128, 88: DRAW OVER 1; sx, sy: REM borrar segundero
400 NEXT t

La "cuerda" de este reloj se acabará en unas 55,5 horas debido a la línea 60, pero fácilmente puede prolongar su período de funcionamiento. Observe cómo la temporización está controlada por la línea 210. Podría esperar PAUSE 50 para hacerle dar un "tic-tac" de un segundo, pero el cómputo lleva algo de tiempo también y ha de permitírselo. Esto es mejor hacerlo por tanteo, sincronizando el reloj del ordenador con uno real y ajustando la línea 210 hasta que concuerden (no puede hacer esta operación con una gran exactitud; un ajuste de un cuadro en un segundo es el 2% o la mitad de una hora en un día).

Hay una manera mucho más exacta de medir el tiempo, utilizando el contenido de determinadas posiciones de memoria. Los datos almacenados se recuperan con el empleo de PEEK. En el capítulo 25 se explicará con detalle. La expresión utilizada es:

(65536 * PEEK 23674 + 256 * PEEK 23673+ PEEK 23672) / 50/div

Nos da el número de segundos desde que el ordenador se puso en marcha (hasta unos 3 días y 21 horas, cuando retorna a 0).

Damos a continuación, un programa de reloj para aplicar lo anterior:

  10 REM Primero, dibujamos el cuadrante del reloj
  20 FOR n = 1 TO 12
  30 PRINT AT 10 - 10 * COS (n / 6 * PI), 16 + 10 * SIN (n / 6 * PI); n
  40 NEXT n
  50 DEF FN t() = INT ((65536 * PEEK 23674 + 256 * PEEK 23673 + PEEK 23672) / 50): REM número de segundos desde puesta en marcha
100 REM Ahora ponemos en marcha el reloj
110 LET t1 = FN t()
120 LET a = t1 / 30 * PI : REM a es el ángulo del segundero en radianes
130 LET sx = 72 * SIN a: LET sy = 72 * COS a
140 PLOT 131, 91: DRAW OVER 1; sx, sy: REM dibujo segundero
200 LET t = FN t()
210 IF t <= t1 THEN GO TO 200: REM esperar hasta tiempo para siguiente segundero
220 PLOT 131, 91: DRAW OVER 1; sx, sy: REM borrar anterior segundero
230 LET t1 = t: GO TO 120

El reloj interno que utiliza este método debe tener una exactitud de un 0,01 % mientras el ordenador esté ejecutando su programa, o lo que es lo mismo, 10 segundos por día; pero se detiene temporalmente siempre que haga BEEP, o una operación de cinta de cassette, o utilice !a impresora o cualquiera de los demás elementos suplementarios de equipos que pueda emplear con el ordenador. Todas estas operaciones le harán perder tiempo.

Los números PEEK 23674, PEEK 23673 y PEEK 23672 se retienen en el interior del ordenador y se utilizan para el contaje en 1 / 50 de segundo. Cada uno está entre 0 y 255 y se incrementan gradualmente a través de todos los números desde 0 a 255; después de 255 pasan directamente a 0.

El que se incrementa más frecuentemente es PEEK 23672. Cada 1 / 50 de segundo se incrementa en 1. Cuando está en 255, el siguiente incremento le lleva a 0 y, al mismo tiempo, impulsa a PEEK 23673 hasta 1. Cuando (cada 250 / 50 segundos) PEEK 23673 se lleva desde 255 a 0, impulsa, a su vez, a PEEK 23674 en 1. Esto debe ser suficiente para explicar por qué opera adecuadamente la anterior expresión.

Ahora, veámoslo detenidamente. Suponga que nuestros tres números son 0 (para PEEK 23674), 255 (para PEEK 23673) y 255 (para PEEK 23672). Ello significa que al cabo de unos 21 minutos después del encendido, nuestra expresión debiera proporcionar:

(65536 * 0 + 256 * 255 + 255) / 50 =1310,7

Pero hay un peligro oculto. La siguiente vez que haya un contaje de 1 / 50 segundo, los tres números cambiarán a 1, 0 y 0. Frecuentemente, esto sucederá cuando esté a medio camino de la evaluación de la expresión: el ordenador evaluaría PEEK 23674 como 0, pero, entonces, cambian los otros dos a 0 antes de que pueda aplicarles la función PEEK. La respuesta sería, entonces:

(65536 * 0 + 256 * 0 + 0) / 50 = 0

que está desesperadamente equivocada.

Una sencilla regla para evitar este problema es evaluar la expresión dos veces en sucesión y tomar la respuesta más grande.

Si examina detenidamente el anterior programa puede ver que cumple con dicha regla de forma implícita.

Veamos un artificio para aplicar la regla. Defina las funciones:

10 DEF FN m(x,y) = (x + y + ABS (x - y)) / 2: REM la más grande de x y de y
20 DEF FN u() = (65536 * PEEK 23674 + 256 * PEEK 23673 + PEEK 23672) / 50: REM tiempo, puede estar equivocado
30 DEF FN t() = (FN u()): REM tiempo, correcto

Puede cambiar los tres números del contador de modo que proporcionen el tiempo real en lugar del tiempo desde que el computador se puso en marcha. Por ejemplo, para ajustar el tiempo a las 10:00 de la mañana, se percatará de que equivale a 10 * 60 * 60 * 50 = 1800000 cincuentavas partes de un segundo y que:

1800000 = 65536 * 27 + 256 * 119 + 64

Para poner los tres números a 27, 119 y 64, hace:

POKE 23674,27: POKE 23673,119: POKE 23672,64

En los países con frecuencias de red de 60 hertzios, estos programas deben sustituir 50 por 60, en donde sea adecuado.

La función INKEY$ (que no tiene ningún argumento) efectúa la lectura del teclado. Si está pulsando exactamente una tecla (o una tecla SHIFT y cualquier otra tecla), entonces, el resultado es el carácter que dicha tecla da en modo L; de no ser así, en cualquier otro modo, el resultado es la cadena vacía.

Pruebe el siguiente programa que opera como una máquina de escribir:

10 IF INKEY$ <> "" THEN GO TO 10
20 IF INKEY$ = "" THEN GO TO 20
30 PRINT INKEY$;
40 GO TO 10

En este caso, la línea 10 espera a que retire su dedo del teclado y la línea 20 espera a que pulse una nueva tecla.

Recuerde que a diferencia con INPUT, INKEY$ no le espera. Por ello no teclee ENTER, pero, por otra parte, si no teclea nada en absoluto, entonces, habrá perdido su oportunidad.

Ejercicios

  1. ¿Qué sucede si omite la línea 10 en el programa de máquina de escribir?

  2. Otra forma de utilizar INKEY$ es una conjunción con PAUSE, como en este programa de máquina de escribir de alternativa.

    10 PAUSE 0
    20 PRINT INKEY$;
    30 GO TO 10

    Para hacer este trabajo ¿por qué es esencial que una pausa no deba acabar si le encuentra pulsando una tecla cuando da comienzo?

  3. Adaptar el programa del segundero de modo que indique también el minutero y la aguja de las horas, dibujándolos cada minuto. Si se considera ambicioso, disponga que cada cuarto de hora haga cualquier "efecto especial" (por ejemplo, podría hacer que diera las campanadas del Big Ben con BEEP). Vea el siguiente capítulo.

  4. (Para sádicos). Pruebe este programa:

    10 IF INKEY$ = "" THEN GO TO 10
    20 PRINT AT 11, 14; "OUCH!"
    30 IF INKEY$ <> "" THEN GO TO 30
    40 PRINT AT 11, 14; "     "
    50 GO TO 10


Manual de Basic Spectrum 48k.