Hasta ahora tenemos dos oleadas de alienígenas y son bastante fáciles de derrotar, pero veo un problema en cómo lo hemos escrito. En el juego espero tener muchos patrones de movimiento distintos para los alienígenas, estoy pensando en un estilo Galaga, o al menos en las partes en las que los alienígenas entran volando en la pantalla.
Con nuestro patrón inicial de alienígenas hubo cierto grado de reutilización de código, pero creo que podemos aprovechar de verdad los comandos DATA & READ de MPAGD para encontrar un enfoque mucho más flexible, que nos permita crear rápidamente infinitos patrones de movimiento de alienígenas (¡o al menos hasta que nos quedemos sin memoria!
Primero crearé un sprite nuevo de nave alienígena:

Voy a empezar un Sprite Type nuevo para mis nuevos alienígenas flexibles... Usaré el Sprite Type 5.
Pensemos en las posibles direcciones en las que puede moverse un alienígena. Creo que las 16 direcciones ampliadas de la rosa de los vientos nos darán suficiente flexibilidad:

Luego escribiremos código de movimiento para cada punto cardinal, usando la variable local DIRECTION, empezando por 0 para N, 1 para NNE y así sucesivamente en el sentido de las agujas del reloj:
EVENT SPRITETYPE5 ANIMATE SLOW ; FLEXI ALIENS ; ===================== IF DIRECTION = 0 ; Move N SPRITEUP SPRITEUP ENDIF IF DIRECTION = 1 ; Move NNE SPRITERIGHT SPRITEUP SPRITEUP ENDIF IF DIRECTION = 2 ; Move NE SPRITERIGHT SPRITERIGHT SPRITEUP SPRITEUP ENDIF IF DIRECTION = 3 ; Move ENE SPRITERIGHT SPRITERIGHT SPRITEUP ENDIF IF DIRECTION = 4 ; Move E SPRITERIGHT SPRITERIGHT ENDIF IF DIRECTION = 5 ; Move ESE SPRITERIGHT SPRITERIGHT SPRITEDOWN ENDIF IF DIRECTION = 6 ; MOVE SE SPRITERIGHT SPRITERIGHT SPRITEDOWN SPRITEDOWN ENDIF IF DIRECTION = 7 ; MOVE SSE SPRITEDOWN SPRITEDOWN SPRITERIGHT ENDIF IF DIRECTION = 8 ; MOVE S SPRITEDOWN SPRITEDOWN ENDIF IF DIRECTION = 9 ; MOVE SSW SPRITEDOWN SPRITEDOWN SPRITELEFT ENDIF IF DIRECTION = 10 ; MOVE SW SPRITEDOWN SPRITEDOWN SPRITELEFT SPRITELEFT ENDIF IF DIRECTION = 11 ; MOVE WSW SPRITEDOWN SPRITELEFT SPRITELEFT ENDIF IF DIRECTION = 12 ; MOVE W SPRITELEFT SPRITELEFT ENDIF IF DIRECTION = 13 ; MOVE WNW SPRITELEFT SPRITELEFT SPRITEUP ENDIF IF DIRECTION = 14 ; MOVE NW SPRITELEFT SPRITELEFT SPRITEUP SPRITEUP ENDIF IF DIRECTION = 15 ; MOVE NNW SPRITELEFT SPRITEUP SPRITEUP ENDIF
Bien, eso definirá cada uno de los movimientos posibles de un alienígena. Ahora solo necesitamos una forma de definir un patrón de movimientos, que podría ser tan simple como una secuencia de valores para DIRECTION y el número de repeticiones.
Así, 8 20 significaría: realiza la DIRECTION 8 (sur) 20 veces.
Si recuerdas nuestro método anterior para mover la primera oleada de alienígenas, iban hacia el sur y luego se desviaban hacia el suroeste,
En nuestro método nuevo eso podría representarse así:
8 20 (sur 20 veces)
7 8 (SSE 8 veces)
6 8 (SE 8 veces)
5 8 (ESE 8 veces)
4 16 (E 16 veces)
Lo cual se presta perfectamente a guardarse en una tabla DATA, por ejemplo:
DATA 8 20 7 8 6 8 5 8 4 16
Después podríamos crear fácilmente patrones nuevos que describan el movimiento de los alienígenas de cada nivel, solo en este evento.
¡Eso debería ser muy eficiente!
Pero hay un par de cosas que necesitaremos para que funcione:
1) Una variable para guardar el número de repeticiones de la dirección de movimiento actual
2) Una forma de encontrar el punto de partida correcto del patrón específico para el nivel / oleada.
El punto 1 es bastante fácil de resolver: simplemente usaremos SETTINGB para leer en ella el número de repeticiones
Usaremos SETTINGA como variable de control, para asegurarnos de que hacemos las cosas en el momento adecuado
Y usaremos JUMPSPEED como contador del número de repeticiones.
Añade el código resaltado a tu evento SPRITE TYPE 5:
EVENT SPRITETYPE5 ; FLEXI ALIENS ; ===================== SPRITEINK C ; Colour the aliens ; FIND THE STARTING POINT FOR THIS LEVEL ;======================================= IF SETTINGA = 0 ; Alien first appears RESTORE ; Restore the data table LET RND = L ; Store the Level number in RND ADD 50 TO RND ; and increase it by 50 WHILE DIRECTION <> RND ; While DIRECTION doesnt = RND READ DIRECTION ; Read value from DATA table READ SETTINGB ; Also read second value ENDWHILE ; Keep going until we find the value in RND LET SETTINGA = 1 ; When we find it change SA to 1 ENDIF ; GET THE NEXT DIRECTION & # REPETITIONS ;======================================= IF SETTINGA = 1 ; Ready to get direction & reptitions READ DIRECTION ; Read the next movement into DIRECTION READ SETTINGB ; Read the repetitions into SettingB LET JUMPSPEED = 0 ; reset the counter LET SETTINGA = 2 ; now we are ready to move ENDIF ; MOVEMENTS ;============== IF DIRECTION = 0 ; Move N SPRITEUP SPRITEUP ENDIF IF DIRECTION = 1 ; Move NNE SPRITERIGHT SPRITEUP SPRITEUP ENDIF IF DIRECTION = 2 ; Move NE SPRITERIGHT SPRITERIGHT SPRITEUP SPRITEUP ENDIF IF DIRECTION = 3 ; Move ENE SPRITERIGHT SPRITERIGHT SPRITEUP ENDIF IF DIRECTION = 4 ; Move E SPRITERIGHT SPRITERIGHT ENDIF IF DIRECTION = 5 ; Move ESE SPRITERIGHT SPRITERIGHT SPRITEDOWN ENDIF IF DIRECTION = 6 ; MOVE SE SPRITERIGHT SPRITERIGHT SPRITEDOWN SPRITEDOWN ENDIF IF DIRECTION = 7 ; MOVE SSE SPRITEDOWN SPRITEDOWN SPRITERIGHT ENDIF IF DIRECTION = 8 ; MOVE S SPRITEDOWN SPRITEDOWN ENDIF IF DIRECTION = 9 ; MOVE SSW SPRITEDOWN SPRITEDOWN SPRITELEFT ENDIF IF DIRECTION = 10 ; MOVE SW SPRITEDOWN SPRITEDOWN SPRITELEFT SPRITELEFT ENDIF IF DIRECTION = 11 ; MOVE WSW SPRITEDOWN SPRITELEFT SPRITELEFT ENDIF IF DIRECTION = 12 ; MOVE W SPRITELEFT SPRITELEFT ENDIF IF DIRECTION = 13 ; MOVE WNW SPRITELEFT SPRITELEFT SPRITEUP ENDIF IF DIRECTION = 14 ; MOVE NW SPRITELEFT SPRITELEFT SPRITEUP SPRITEUP ENDIF IF DIRECTION = 15 ; MOVE NNW SPRITELEFT SPRITEUP SPRITEUP ENDIF ; BOUNDARY CHECKING ; =================== IF X <= LEFTEDGE ; if alien reaches the left edge REMOVE ; remove it SUBTRACT 1 FROM S ; decrement the sprite counter SUBTRACT 1 FROM F ; decrement the number of aliens still in ENDIF IF X >= RIGHTEDGE ; if alien reaches the right edge REMOVE ; remove it SUBTRACT 1 FROM S ; decrement the sprite counter SUBTRACT 1 FROM F ; decrement the number of aliens still in ENDIF IF Y >= BOTTOMEDGE ; if alien reaches the right edge REMOVE ; remove it SUBTRACT 1 FROM S ; decrement the sprite counter SUBTRACT 1 FROM F ; decrement the number of aliens still in ENDIF ; INCREMENT REPETITION COUNTER & CHECK IF WE NEED NEXT DIRECTION ;============================== SUBTRACT 1 FROM SETTINGB ; decrement the number of repetitions IF SETTINGB = 0 ; have we done all the required repetitions LET SETTINGA = 1 ; yes, request the next direction ENDIF ; MOVEMENT & REPETITIONS DATA TABLE DATA 51 0 8 20 7 8 6 8 5 8 4 16 DATA 5e2 0 8 20 9 8 10 8 11 8 12 16
Primero, he añadido un comando spriteink para colorear a los alienígenas con el valor C (lo añadiremos a la tabla de datos del spawner dentro de un momento)
Así, cuando este evento se ejecute por primera vez para un sprite alienígena, SettingA valdrá 0 (tendremos que añadirlo a Initialise Sprites dentro de un momento)
Esto restaurará la tabla de datos (lo que significa que el siguiente READ será el primer valor de la tabla). Después recorreremos los datos hasta encontrar un valor igual a 50 + el número de nivel (es decir, para el nivel 1 buscamos 51, para el nivel 2 buscamos 52 y así sucesivamente).
Elegí 50 porque es improbable que necesite más de 50 direcciones (0-15 representan nuestros 16 puntos cardinales), pero me deja margen para añadir más después y significa que podría tener más de 200 patrones de movimiento en este evento, lo que debería ser más que suficiente.
Una vez que lo hayamos encontrado, leeremos el número siguiente en SETTINGB (usaremos simplemente 0) y pondremos SettingA a 1 para no restaurar los datos en cada ciclo.
Es importante entender que cada sprite sabe siempre hasta dónde ha leído de la tabla de datos, a menos que hagamos un RESTORE, momento en que vuelve al principio.
Ahora que SettingA vale 1, haremos un READ del número de DIRECTION y del número de REPETITIONS necesarias en SETTINGB, y luego pondremos settingA a 2 para evitar que esto se ejecute de nuevo hasta que se hayan realizado todas las repeticiones de la dirección de movimiento.
Ten en cuenta que también he puesto una comprobación de límites (no muy eficiente, la mejoraremos más adelante) que eliminará a los alienígenas que salgan de la pantalla.
Por último, tenemos nuestra tabla DATA. Por el momento he replicado nuestros dos patrones de movimiento originales: bajar y desviarse a la derecha, y bajar y desviarse a la izquierda.
Bien, antes de probarlo nos quedan un par de tareas más.
MENÚ: EVENTS > INITIALISE SPRITES:
EVENT INITSPRITE ADD 1 TO S ; increment the sprite counter IF TYPE 1 ; PHOTON TORPEDO LET SETTINGB = 0 ; initialise the distance counter ENDIF IF TYPE 5 ; FLEXI ALIENS LET SETTINGA = 0 ; Initialise SettingA ENDIF IF TYPE 7 ; SPAWNER LET SETTINGA = 0 ; RESET SETTINGA ENDIF
A continuación, actualizaremos el código del evento del Spawner:
EVENT SPRITETYPE7 ; SPAWNER ; ============ IF SETTINGA = 0 ; first time we run this LET JUMPSPEED = 0 ; reset the enemies spawned counter LET SETTINGB = 0 ; reset the timer RESTORE ; start from the beginning of the data table REPEAT L ; get the data for this level READ AIRBORNE ; get the spawner movement READ X ; get starting x position READ Y ; get starting y position READ J ; get the enemy sprite type READ K ; get the enemy image READ E ; how many enemies in this level? READ G ; delay between releasing each enemy READ P ; Number of points scored if enemy is killed READ C ; get the colour value for the alien ENDREPEAT LET D = E ; store the number of enemies to be killed in D LET F = E ; also store #enemies in F to count kills & exits ADD 1 TO SETTINGA ; prevent this running again ENDIF IF SETTINGB = G ; has timer reached the delay point? IF JUMPSPEED < E ; are there still enemies left to spawn? IF S <= 8 ; are there 10 or less enemies already on screen? SPAWN J K ; spawn an enemy ADD 1 TO JUMPSPEED ; increment the number spawned SPAWNED ; switch to the enemy sprite LET DIRECTION = 0 ; set its initial direction to 0 ENDSPRITE ; return to the spawner ENDIF ELSE ; all enemies in this level have been spawned IF F = 0 ; if all enemies killed or exited ADD 1 TO L ; get ready for next level IF L = 3 ; have we reached the end of the levels? LET L = 1 ; yes, start again ENDIF LET SETTINGA = 0 ; GET DATA FOR NEXT LEVEL ENDIF ENDIF LET SETTINGB = 0 ; reset the timer ENDIF ADD 1 TO SETTINGB ; increment the timer DATA 0 132 8 5 2 8 8 5 67 DATA 0 100 8 5 2 8 8 10 68
Aquí he añadido un valor nuevo a cada conjunto de datos y he separado los dos niveles en líneas propias para que sea más fácil de leer. El valor nuevo (el noveno) es el que se leerá en C.
¡Creo que estamos listos para probar! ¡Vamos a compilar a este bicho!
¡Sí! ¡Mira cómo vuelan!
Vale, ahora vamos a divertirnos y a crear algunos patrones nuevos en la tabla DATA del sprite type 5. Asegúrate de empezar cada patrón con 200+Nivel# seguido de un cero y luego tus pares de DIRECTION # y Repetition #
Prueba estos para empezar, y luego inventa los tuyos:
Sustituye la tabla DATA de tu evento de alienígena (Sprite Type 5) por:
DATA 51 0 8 20 7 8 6 8 5 8 4 16 DATA 52 0 8 20 9 8 10 8 11 8 12 16 DATA 53 0 12 48 11 2 10 2 9 2 8 2 7 2 6 2 5 2 4 40 5 2 6 2 7 2 8 2 9 2 10 40 DATA 54 0 4 48 5 2 6 2 7 2 8 2 9 2 10 2 11 2 12 40 11 2 10 2 9 2 8 2 7 2 6 40 DATA 55 0 13 26 14 4 15 4 0 4 1 4 2 4 3 4 4 4 5 4 6 4 7 4 8 4 9 4 10 40 DATA 56 0 3 26 1 4 0 4 15 4 14 4 13 4 12 4 11 4 10 4 9 4 8 4 7 4 6 40
Y sustituye la tabla de datos de tu Spawner (Sprite Type 7) por:
DATA 0 132 8 5 2 8 8 5 67 DATA 0 100 8 5 2 8 8 10 68 DATA 0 232 16 5 5 8 6 15 69 DATA 0 8 16 5 5 8 6 15 70 DATA 0 232 146 5 2 16 6 20 71 DATA 0 8 146 5 2 16 6 20 66
Ahora que tenemos 6 oleadas de ataque / niveles, tendrás que actualizar esta línea en el evento de tu spawner
IF L = 3 ; have we reached the end of the levels?
a:
IF L = 7 ; have we reached the end of the levels?
Guarda tu juego, ¡y vamos a compilarlo y a disparar a unos cuantos alienígenas!
¡Genial! ¡Siéntete libre de experimentar y de crear muchos más patrones de ataque!
Sin embargo, ya va siendo hora de darles a los alienígenas armas propias. Si nos apoyamos en la estructura que ya hemos creado y usamos algunos de los trucos que hemos aprendido, deberíamos poder añadir mucha más variedad al juego.
SIGUIENTE: Parte 9: ¡Los alienígenas contraatacan!
