Volver menú revistas Volver página anterior

El Amiga Me Encanta ha conseguido el permiso por escrito de IDG Comunications España para ofrecer los artículos de la revista Amiga World España.

N° 43 - Mayo 1993
Amiga World

AMOS


EL LENGUAJE DEL MOVIMIENTO

Por Mark Jordan

Cuando conseguí el AmigaBasic de
Microsoft para mi Amiga, no podía
esperar a probar los comandos
sprite y BOB que parecían tan
prometedores en la documentación.
¡Qué suerte!. Incluso había un
programa de ejemplo en el disco.
Arranqué mi ordenador, me senté
y, ... eh, espere un momento,
¿se supone que éste es el PC más
potente en gráficos del mundo?.
Los sprites no se lanzaban a través
de la pantalla, tropezaban por ella.

 

Más tarde, otros BASIC entraron en el mercado, pero era siempre la misma historia. Trompicones, trompicones y trompicones. Pensé que me iba a dar algo ... y empecé a dudar de mi Amiga.

Ahora debo disculparme. Necesité un programa de Inglaterra, escrito por un francés, para reafirmar mi fé en el ordenador con el nombre en español.

El programa era AMOS (Europress Software). Es un lenguaje BASIC que todo el mundo puede utilizar, con más de 500 comandos potentes y creativos. Y AMOS no sólo tiene este gran vocabulario, tiene el sublenguaje AMAL. ¿Qué es AMAL?.

- un acrónimo para AMos Animation Language.

- Un híbrido entre BASIC y lenguaje máquina que mueve sus sprites deslizándolos, los BOBs con movimiento fluidos y pantallas enteras con gran suavidad.

- un camino para programar interrupciones de forma rápida, potente y no muy dificil de aprender.

Empecemos con un rápido repaso del concepto de AMAL y echemos un vistazo a programas reales en acción.


CADENAS, GRAMATICA Y CANALES

AMAL, es un sublenguaje que está dentro de AMOS, con su propio set de 14 comandos y 15 funciones. Ninguno de los cuales, sin embargo, puede ser usado directamente desde BASIC. ¿Y cómo accedemos a ellos?. Mediante cadenas, como en:

M$="Let Y=Y+1"

Los subprogramas en AMAL se deben escribir dentro de variables de cadena en BASIC, lo que requiere cierta costumbre.

Si el programa se hace demasiado grande, será necesario añadir cadenas, como:

M$=M$+"Let X=X+1"

Para propósitos de depuración, es una buena idea usar variables de cadena globales de forma que el programa pueda imprimir en modo directo para su estudio.

No hace falta hojear mucho a través de la sección de AMAL en el manual de AMOS, para ver que tiene, digamos, una sintaxis peculiar. Las variaciones más importantes respecto del BASIC que hay que manejar son:

1. Sólo las mayúsculas tienen sentido para AMAL:
2. El punto y coma, no los dos puntos, se usan como separador de comandos.
3. Los dos puntos se emplean para designar etiquetas.
4. No existe Then, únicamente Jump.
5. Los bucles For/Next usan registros, no variables.

Los canales son otros conceptos importante de AMAL; son para los programas en AMAL, lo que los números de archivo para los discos de archivo. Una vez que se asigna un canal a un objeto en particular (por ejemplo, el canal 1 al sprite 8), todas las operaciones bajo ese canal se aplicarán únicamente a ese objeto. AMAL permite tener hasta 64 canales diferentes, lo que significa que se pueden tener hasta 64 sprites, BOBs y pantallas moviéndose simultáneamente.

O se puede dedicar más de un canal a un solo objeto. Por ejemplo, se podrían asignar dos canales al mismo objeto, uno para mover el objeto y otro para ejercer un tirón "gravitacional" del mismo. Debido a que los programas de AMAL continúan hasta que se les detenga, una sola llamada al canal de la "gravedad" funcionará a lo largo de todo el programa. El potencial de este punto es extraordinario.


INTERRUPCIONES

Las interrupciones son parte del sistema operativo de cualquier ordenador; cada sesentava parte de segundo, la CPU deja lo que está haciendo y salta a un programa especial, que realiza tareas (como leer el teclado) de las que la mayoría de nosotros no nos damos cuenta. Una vez que finaliza, regresa a su tarea principal, el programa en uso. Una secuencia muy simplificada del proceso sería:

Paso 1: Señal desde el reloj del sistema: es el momento de una interrupción.
Paso 2: Detener el programa principal, saltar a la interrupción.
Paso 3: Realizar la rutina en interrupción.
Paso 4: Volver al programa principal.

A los programadores en lenguaje máquina les encantan estas interrupciones ya que pueden deslizar sus propias rutinas en las interrupciones del ordneador, dando así sus programas una forma de multitarea. El lenguaje máquina solía ser el único camino de emplear las interrupciones en programas. Ahora, con AMOS, las interrupciones pueden ser usadas en los comandos de música (así es como se puede utilizar música mientras se ejecuta un programa), controlando el reloj del sistema, en menus y en otras muchas áreas. Todo esto está bien, pero todas son tareas de interrupción predefinidas. Sin embargo, AMAL permite escribir rutinas propiasintroduciéndose en algún punto del paso 3 que vimos.

Los refrescos de pantalla están claramente relaciona-
dos con las interrupciones, ya que ocurren 60 veces
por segundo. AMAL puede coordinar un programa con
el período entre el cual la pantalla se refresca.

Los refrescos de pantalla están claramente relacionados con las interrupciones, ya que ocurren 60 veces por segundo. AMAL puede coordinar un programa con el período entre el cual la pantalla se refresca (llamado VBL, de vertical blank period). Esto da a los programadores de BASIC más control sobre el movimiento de los objetos que cualquier otro lenguaje, incluso que el lenguaje máquina, pero eso lo veremos más tarde.

Una vez que los programadores de AMOS se acostumbran a AMAL, se encontrarán preguntándose si es mejor usar AMAL para mover objetos o si es más simple hacerlo en AMOS. La respuesta es la siguiente: cuando funciona bien con AMOS, utilícelo; en otro caso use AMAL: Si no tiene el compilador de AMOS, probablemente elegirá AMAL casi siempre. AMAL es capaz de crear un juego completo, siendo las únicas tareas del programa principal comenzar la acción, guardar la puntuación y anunciar el ganador.


AMAL EN ACCION

Una vez que haya comprendido los conceptos principales de AMAL, el siguiente paso es aprender sus comandos. Aunque su número es pequeño y el manual explica cada comando claramente, no es tan sencillo acostumbrarse a ellos.

En lugar de destrozar el manual repasándolo, podemos aprender más sobre estos comandos creando un programa ejemplo, que lee el joystick y mueve un sprite de acuerdo con él. Esta rutina es parte de un programa sencillo, una variante del viejo Ping-Pong, que incluye en el listado 1. Lo incluyo principalmente como ejemplo, pero no permite que ésto impida teclearlo y jugar. Es muy divertido.

Para el movimiento, usaremos el sprite 9 (es decir, la pala). Epecemos creando la cadena de AMAL:

M$="Loop:IfJ1&1=1 Jump Up;"

Como la mayoría de los programas en AMAL; éste comienza con una etiqueta, en este caso la palabra "Loop". La razón es que los programas en AMAL, en su mayor parte, son bucles, y una etiqueta en AMAL es la única manera de identificar los puntos de salto. La única letra que importa en la etiqueta es la letra L. El resto, todas minúsculas, son sólo útiles para el programador como indicación de qué hace la etiqueta. Cuando se escriben subprogramas en AMAL, debe recordar no usar etiquetas que comiencen con la misma letra ya que AMAL podría confundirse.

Si desea incluir algo de movimiento en los juegos u
otros programas que cree, el sublenguaje especial de
animación de AMOS, AMAL, puede ofrecerle movimien-
tos suaves a velocidades de vértigo.

De repente las cosas se ponen crípticas: ¿qué hace esto de "J1&1" dentro de un If?. J1 es una función de AMAL, que lee el joystick 1. En "&1", el ampersand (&) es la forma de AMAL de realizar un AND Booleano. Ya que no hay espacio para explicar la lógica Booleana, todo lo que necesita saber es ésto: haciendo AND con los valores del joystick con 1,2,4,8 y 16 le dirá, respectivamente, si el joystick está siendo empujado arriba, abajo, izquierda, derecha o el botón está siendo pulsado. Si J1 AND 1 (J1&1) es cierto (mayor que 0), entonces el joystick debe estar siendo pulsado hacia arriba.

Ahora podemos ver lo que hace la sentencia If. Si J1&1 es cierto, saltamos a la rutina Up. Si la sentencia es falsa, entonces pasamos al siguiente comando:

M$=M$+"IfJ1&2=0 J L;"

Primero, note cómo se utiliza la adición de cadenas. También fíjese en que cada línea termina con un punto y coma. Aunque el punto y coma no se requiere como separador de comandos, es más seguro incluirlos. Esta sentencia If se parece mucho a la anterior. las únicas diferencias son, en primer lugar, que comprueba que se empuja haciaabajo (mediante &2) y, en segundo, que trabaja en sentido inverso, pues salta bajo la condición de que el joystick no esté siendo empujado hacia abajo. Fíjese en que he eliminado las minúsculas del comando Jump Loop, leyéndose simplemente "J L". Funciona igualmente, ahorra algo de tiempo, y después de usar durante un tiempo AMAL tendrá el mismo sentido para usted.

De acuero, así que si nosotros fallamos, el joystick debe ser pulsado hacia abajo. ¿Y ahora qué?. Probemos con esto:

M$=M$+"if Y>228 J L;LET Y=Y+1;J L;"

Las cosas parecen claramente lógicas, sólo otro If/Jump, excepto por la "Y". Esta, como la X y la A, son registros reservados, variables dentro de cada canal que informan de las coordenadas Y (verticales), coordenadas X (horizontales) y el número de sprite, respectivamente. Ya que esta rutina de la pala debe ser dirigida al canal del sprite 9, el valor en Y será siempre la coordenada Y de ese sprite. Si este valor de Y es mayor de 228, estaremos en el fondo de la pantalla, en cuyo caso no haremos nada y volveremos al comienzo. Si no lo es, incrementaremos el valor de Y usando el comando Let, y volveremos al inicio.

Con AMAL se puede crear prácticamente un juego
completo, en el que el programa principal se
encargaría sólo de comenzar la acción, guardar la
puntuación y anunciar el ganador.

¿Quiere que su pala se mueva más rápido? Basta con sumar dos, o más, a Y. ¿Quiere que su pala se mueva más despacio?. Sólo debe situar un comando Pause al comienzo del bucle, de esta forma:

M$="Loop:Pause ;IfJ1&1 Jump Up;"

El comando Pause detiene la rutina hasta el siguiente VBL (vertical blank), con la intención de coordinar el programa en AMAL con el refresco de pantalla. Esto significa que el programa en AMAL hará un sólo bucle en cada interrupción, lo cual no es una mala idea, ya que acelerará el programa principal en AMOS sin ninguna pérdida de suavidad de movimientos en la animación. De hecho, se puede usar el comando Pause y el aumento de velocidad de los objetos (sólo con aumentar el incremento en pixels), sin ninguna pérdia de resolución (por ejemplo, Let Y=Y+3).

Otro método de alcanzar el mismo objetivo es incluir un bucle For/Next en el mismo punto, como en:

M$="Loop:for R0=1 To 5;Next R0 ..."

La opción del For/Next es muy flexible debido al modo en que AMAL trata con los bucles For/Next; realiza un solo paso por interrupción. En otras palabras, ofrece una especie de Pause por cada paso de bucle. La línea de arriba haría la pala cinco veces más lenta.

Como cabía suponer, la rutina Up (para cuando el joystick se pulsa hacia el norte) es muy parecida a la rutina Down:

M$=M$+"Up:If Y>52 J L;LET Y=Y-1:J L;"

Aquí reducimos Y si es mayor que 52 y saltamos al inicio del bucle para comenzar de nuevo.

Nuestra rutina AMAL en sí ha sido escrita. Lo único que queda por hacer es encender este subprograma en AMAL. Una vez hecho, puede olvidarse de comprobar los joystick en BASIC, ya que AMAL lo mantendrá funcionando incluso cuando el programa termine. Sólo teclee:

AMAL9,M$:AMAL On 9

No me queda más espacio para examinar detalladamente el artículo, pero he dejado algunas notas en el listado para su estudio. Animo a los lectores interesados a prestar especial atención al procedimiento MOVEBALL, que demuestra cómo usa AMOS sus capacidades de movimiento de sprites en tándem con las de AMAL. El resultado es una pelota que bota a diversas velocidades y ángulos.

Un sólo artículo no es suficientepara introducirnos profundamente en AMAL, piense sólo que AMAL representa el 5% del paquete completo AMOS. Europress ha sacado también al mercado una versión aun más potente, AMOS Professional.

Encabezado 1ª pagina: Si desea incluir algo de movimiento en los juegos u otros programas que cree, el sublenguaje especial de animación de AMOS, AMAL, puede ofrecerle movimientos suaves a velocidades de vértigo.

Dim SCORE(2)
Global N$,S1$,S2$,OFF,GAMEOVER,SCORE(),LEVE
Do
    SETUP
    MOVEPADDLE
    '
    Repeat
        STRTPOINT
        MOVE
        SCORE
    Until GAMEOVER
Loop
'
Procedure SETUP
    SX=0:S1=0:S2=0:GAMEOVER=0
Rem Crear Sprite Ball
    Screen Open 0,320,200,32,Lowres
    Curs Off:Cls 0:Hide
    Ink 14:Circle 9,9,5:Paint 10,10
    Get Sprite 1,0,0 To 15,15
Rem Crear Sprite Paleta
    Cls 0:Ink 15:Box 0,0 To 6,20:Paint 1,1
    Get Sprite 2,0,0 To 15,20
Rem Selecionar Nivel,Jugadores
    Cls 0:Centre "Elige Nivel: 1(Difícil) - 5(Fácil)":
Print
    Repeat: A$=Inkey$:Until A$<>""
    LEVEL=Val(A$):If LEVEl > 5 Then LEVEL=5
    Centre "¿1 ó 2 Jugadores?"
    Repeat: A$=Inkey$:Until A$<>""
    TWO=Val(A$):If TWO > 2 > Then TWO=1
Rem Extraer la caja Pong
    Cls 0:Ink 4:Box 0,0 To 319,199
Rem Establecer sprites para la detección de colisión
    Make Mask:Hot Spot 1,$11
    Sprite 0,128,130,2:Sprite 10,441,130,2
    SCORE(1)=0;SCORE(2)=0
End Proc
'
Procedure STRTPOINT
    Sprite 8,283,0,1:Amal Off 10
Rem Bajar la bola a la situación inicial
    Amal 8,"M 0,241,73:Let RA=Y":Amal On 8
Rem Esperar hasta que pare de moverse
    While Chanmv(8):Wend
Rem Activar la paleta del ordenador
    Amal 10,N$:Amal On 10
End Proc
Procedure MOVEBALL
    OFF=0:RV=-1:If Rnd(1) Then RV=-RV
    Do
    Rem RV decidirá el camino a seguir por la bola, RX el ángulo
    Z=0:RV=-RV:RX=360*RV:Amreg(3)=RV
Rem SP es la velocidad de la bola, AD afecta al ángulo
    Y=Y Sprite(8):SP=Rnd(40)+60:AD=Rnd(5)+1
Rem Preparar el comando Amal Move para movimiento horizontal en velocidad SP
    B$="M"+Str$(RX)+",0,"+Str$(SP)
    Amal 8,B$:Amal On 8
rem Empezar la trayectoria en bucle de la bola
    Repeat:
        Rem Comprobar si la bola pasa o no a la paleta
        If Y<54 Then Y=54:AD=AD
        If Y>241 Then Y=241:AD=-AD
Rem Cambiar la colocación Y de la bola directamente desde Amos, no Amal
    Add Y,AD:Inc Z
Rem Pero esperar a que el vacío vertical lo mueva
    Wait Vbl:Sprite 8,,Y,
Rem establecer el register 0 Amal (RA) con el valor Y de la bola
    Amreg(0)=Y Sprite(8)-10
Rem Si la bola sobrepasa la salida de la paleta se mueven en bucle
    SX=X Sprite(8)
    If SX<122 Then OFF=2:Exit 2
    If SX>452 Then OFF=1:Exit 2
Rem Otro caso aparte es si la bola colisiona con la paleta
    Until Sprite Col(8) and Z>5
    Amal Off 8
Loop
End proc
'
Procedure MOVEPADDLE
    Rem La rutina de la paleta está explicada en el artículo
    M$="Loop: IfJ1&1 Jump Up;"
    M$=M$+"IfJ1&2=0 J L;"
    M$=M$+"If Y>228 J L; Let Y=Y+1; J L;"
    M$=M$+"Up: If Y<52 J L; Let Y=Y-1; J L;"
    Amal 9,M$: Amal On 9
'
Rem Si juegan dos jugadores, convertir todos los J1 en J0 (otro joystick)
    If TWO="
    N$=M$:Do:P=Instr(N$,"J1")+1:Exit If P=1:Mid$(N$,P)="0":Loop
    Rem Si un jugador
    Else
        Rem Encontrar diferencias entre el Y de la bola (RA) y el (Y) de la paleta
        N$=N$+"Loop:Let R1=RA-Y;"
    Rem Introducir diff como distancia y en el comando Move
    Rem Y en la velocidad seleccionada por LEVEL
    N$=N$+"M 0,R1,"+Str$(LEVEL+2)+"J L"
  End If
End Proc
Procedure SCORE
    SCORE(OFF)=SCORE(OFF)+1
    Pen 5:Paper 0
    Locate 7,1:Print SCORE(1)
    Locate 30,1:Print SCORE(2)
    If SCORE(OFF)>19
        Locate 6+(OFF 1)*23,2:Pen 3:Print "¡Ganador!"
        GAMEOVER=1:Wait 240
  End If
End Proc

Volver menú revistas Volver página anterior