EL JUEGO
El juego original se publico en el año 1982 y fue programado para ZX-81 con 16K.
El objetivo del juego consiste en destruir los Fungaloids antes que lleguen a la parte superior de la pantalla. Estas plantas crecen y disparan unas esporas que nos destruyen si nos alcanzan. Debemos evitar chocar con ellos o con los distintos enemigos que hay en la zona.
Nuestra única nave tiene una capacidad limitada de combustible y munición, y periódicamente debemos repostar en las zonas correspondientes.
Al destruir todos los segmentos de los Fungaloids recibimos 100 puntos, pasamos de nivel y aumenta la dificultad.
Cerca de la base de algunos Fungaloids hay unas construcciones. Si destruimos una perdemos 20 puntos.
EL juego finaliza si perdemos nuestra única vida o si perdemos todos los puntos.
Controles:
Q-A-O-P para mover la nave y SPACE para disparar.
Descargar el juego en formato TAP:
BLOQUES
He dividido el listado en 11 bloques:
- Declaración de matrices e inicio del juego.
- Control de nuestra nave.
- Mover enemigos.
- Control del disparo.
- Control del proyectil enemigo.
- Final del Juego.
- Pasar Nivel.
- Presentación.
- Mostrar pantalla de juego e inicializar variables.
- Rutinas varias.
- Bloque de datos.
COMO FUNCIONA
Todo el programa ocupa 82 líneas.
A continuación indico el principio de las distintas partes del programa:
10 - Definimos las matrices del juego.
100 - Leemos el teclado: si no se pulsa una tecla salta a 170, sino se borra la nave de la pantalla.
160 –Comprobamos que hay en la posición de la nave. Si hay algo distinto a espacios salta a 600.
200 - Código que decide que enemigo hemos de mover: 0- Barrera de energía, 1- Naves enemigas y 2- Fungaloids.
210 - Rutina de movimiento de la barrera de energía.
240 - Rutina de movimiento de una de las tres naves.
270 - Rutina de movimiento de uno de los seis Fungaloids.
300 - Control de nuestro disparo.
400 - Control de disparo del Fungaloid.
450 - Miramos los 3 caracteres que hay en la posición de nuestra nave. Si no corresponden a la nave significa que hemos chocado con algo y salta al final del juego, en caso contrario se vuelve al principio del bucle.
600 - Final de partida.
700 - Pasar nivel.
800 – Rutinas varias: Cargar munición (820), cargar combustible (850), mostrar puntuación (880).
900 – Rutina para imprimir nuestra nave en la posición correspondiente.
2000 - Pantalla de presentación.
2500 - Dibujamos la zona de juego.
2800 - Inicializamos las variables del juego.
3000 – Cargamos los gráficos e inicializamos ciertas variables.
9000 - Datos de las posiciones iniciales verticales de los 6 Fungaloids.
EL LISTADO
Código: Seleccionar todo
' Declaración de matrices, variables e inicio del juego
10 DIME(6),P(6),V(3),H(6),J(3),C$(8)
30 GOSUB3000:GOSUB2000
' Control de nuestra nave
100 K=PEEK(520):IFK=56THEN170ELSEPLOTX,Y," "
120 IFK=149THENIFX>2THENX=X-1:A=A-1:GOTO160
130 IFK=157THENIFX<35THENX=X+1:A=A+1:GOTO160
140 IFK=177THENIFY>0THENY=Y-1:A=A-40:GOTO160
150 IFK<>174THEN160
152 IFD=0ORA+42<DTHENY=Y+1:A=A+40:IFY=19THEN800
160 IFDEEK(A)+PEEK(A+2)<>8256THENGOSUB900:GOTO600
170 GOSUB900:IFGTHENG=G-1:GOTO200
180 G=10:C=C-10:PLOT10,24,STR$(C)+" ":IFCTHEN300ELSE600
' Mover enemigos
200 GOTOJ(RND(1)*3)
210 IFRND(1)>.3THENIFM>T1THENM=M-40:POKEM,107:GOTO300
220 IFM<T2THENPOKEM,32:M=M+40:GOTO300ELSE300
240 F=RND(1)*3:POKEV(F),32
250 IFRND(1)>.5THENIFV(F)>T1THENV(F)=V(F)-40:POKEV(F),106:GOTO300
260 IFV(F)<T2THENV(F)=V(F)+40:POKEV(F),106:GOTO300ELSE300
270 F=RND(1)*L:IFF>5THEN300
280 T=T+1:P(F)=P(F)-40:POKEP(F),101:IFP(F)<T1THEN600
' Control de nuestro disparo
300 IFDTHENPOKED,32:GOTO335
310 IFK<>132ORB=0THEN400
320 D=A+1:DX=X+1:B=B-1:PLOT26,24,STR$(B)+" "
335 D=D+40:F=PEEK(D):IFF=32THENPOKED,105:GOTO400
340 IFF=112THENPOKED,32:S=S-20:GOTO360
345 IFF<>101THEND=0:GOTO400
350 POKED,32:T=T-1:S=S+1:GOSUB880:F=(DX-1)/5-1:P(F)=P(F)+40
355 IFO=0THENY1=E(F)-40:F1=F:O=1
360 IFS<0THENS=0:GOSUB880:GOTO600ELSEGOSUB880
365 D=0:IFT=0THEN700
' Control disparo Fungaloid
400 IFO=0THEN450
420 IFY1>=P(F1)THENPOKEY1,101ELSEPOKEY1,32
440 IFY1>T1THENY1=Y1-40:POKEY1,100ELSEO=0
450 IFDEEK(A)+PEEK(A+2)=25284THEN100
' Final de partida
600 PLOT15,11," GAME OVER ":EXPLODE:WAIT500:GETA$:GOSUB2000:GOTO100
' Pasar nivel
700 PLOT15,11," WELL DONE ":PING:WAIT300:IFL>10THENL=L-4
710 S=S+100:GOSUB880:CLS:GOSUB2500:GOTO100
' Rutina: Recargar combustible, Munición y Marcador Puntos
800 IFX=2THEN850
810 IFX<>35THEN160
820 GOSUB900:FORF=14TO1STEP-.05:PLOT35,21,MID$("ggg iii ii gg",F,3):NEXT
825 IFTB<30THENB=TB:F=BELSEF=30-B:B=30
830 TB=TB-F:PLOT26,24,STR$(B)+" "
835 PLOT32,24,RIGHT$("000"+MID$(STR$(TB),2),4):GOTO200
850 GOSUB900:FORF=1TO14STEP.05:PLOT2,21,MID$("gg nn nn n ggg",F,3):NEXT
855 IFTC<500THENC=TC:F=CELSEF=500-C:C=500
860 TC=TC-F:PLOT4,24,RIGHT$("000"+MID$(STR$(TC),2),4)+" l"+STR$(C)+" "
865 GOTO200
880 PLOT18,24,RIGHT$("0000"+MID$(STR$(S),2),5):RETURN
' Imprimir nuestra nave
900 PLOTX,Y,"abc":RETURN
' Presentación
2000 CLS:PLOT14,0,C$(2)+"FUNGALOIDS"
2010 PLOT2,3,C$(3)+"THE FUNGALOIDS ARE GROWING AND WHEN"
2015 PLOT4,4,C$(3)+"THEY REACH THE SKY THEY PRODUCE"
2020 PLOT3,5,C$(3)+"DEADLY SPORES. YOUR MISSION IS TO"
2025 PLOT 4,6,C$(3)+"DESTROY THE FUNGALOIDS DROPPING"
2030 PLOT 6,7,C$(3)+"ANTI-FUNGUS BOMBS ON THEM."
2035 PLOT8,11,C$(1)+"PRESS ANY KEY TO START":S=0:L=30
2040 PLOT9,26,C$(6)+"(C) SCAINET SOFT, 2015":GOSUB2505:GOSUB900:GETA$:CLS
' Mostrar zona de juego
2500 V(0)=48373:V(1)=48498:V(2)=48263:FORF=0TO2:POKEV(F),106:NEXT
2502 PLOT2,0,"qqqqqqrrrrrrrrssssssssrrrrrrrrqqqqqq"
2505 FORF=0TO22:PLOT1,F,CHR$(VAL(MID$("11111333333666666222222",F+1,1))):NEXT
2510 PLOT28,18,"fgggh":PLOT23,19,"ppfggggggggh":PLOT20,20,"fgggggggggggggg"
2515 PLOT2,20,"momh":PLOT35,20,"mom"
2520 PLOT2,21,"gggggh p pfgghpfgggggggggggggggggg":PLOT29,17,"pp"
2530 PLOT2,22,"gggggggggggggggggggggggggggggggggggg"
2540 FORF=23TO25:PLOT1,F,C$(4)+"llllllllllllllllllllllllllllllllllll":NEXT
2550 PLOT1,24,C$(4)+"l 9000 l 500 ll ll 30 l 1000 ":GOSUB880
2560 PLOT3,23,"tu":PLOT34,23,"vwx"
' Inicializar variables del juego
2800 E(0)=48886:E(1)=48931:E(2)=48896:E(3)=48861:E(4)=48826:E(5)=48791:G=10
2810 FORI=1TO5:FORF=0TO5:P(F)=E(F)-I*40:POKEP(F),101:NEXTF,I:M=48833
2830 X=2:Y=13:A=48562:GOSUB900:C=500:B=30:D=0:O=0:T=30:TB=1000:TC=9000:RETURN
2840 V(0)=48373:V(1)=48498:V(2)=48263:FORF=0TO2:POKEV(F),106:NEXT:RETURN
3000 CLS:INK7:PAPER0:T1=48120:T2=48833:POKE#BBA3,0:POKE#26A,10
3010 FORF=46856TO47047:READD:POKEF,D:NEXT:J(0)=210:J(1)=240:J(2)=270
3020 FORF=0TO8:C$(F)=CHR$(F):NEXT:RETURN
' Gráficos UDG
9000 DATA63,15,16,40,17,3,1,6,63,63,12,30,33,45,63,30,63,60,2,5,34,48,32,24
9010 DATA12,30,45,18,12,18,30,12,6,7,22,22,12,13,30,12,3,6,15,11,30,31,59,63
9020 DATA55,61,47,59,62,55,31,61,48,56,28,54,62,59,47,63,0,18,12,12,30,30,12,0
9030 DATA18,45,12,18,63,18,45,30,26,41,22,37,26,41,22,37
9040 DATA63,63,63,63,63,63,63,63,30,63,18,12,18,12,51,63
9050 DATA58,36,62,34,46,34,46,62,63,63,18,12,12,18,51,63,62,34,28,20,28,20,20
9070 DATA62,0,0,0,0,63,42,63,0,0,0,0,63,42,63,0,0,0,0,63,42,63,0,0,0
9080 DATA63,7,26,10,26,26,24,63,63,63,37,45,37,45,36,63
9090 DATA63,35,42,38,42,42,34,63,63,63,9,42,42,42,11,63,63,63,8,42,41,42,40,63
APUNTES FINALES
Esta es una nueva versión de uno de mis juegos favoritos para el ZX-81. Después de una versión para MSX y SHARP MZ-700 me he decidido a realizar una versión "Cellophane Edition" para el ORIC, donde me he trabajado más la parte gráfica, y he adaptado el juego a 36 columnas, en lugar de las 32 originales o las 40 del MZ-700.
Por un lado, me habría gustado colorear el juego de otra forma pero las limitaciones del ORIC me lo han impedido, de forma que he decidido presentarlo como se ve, algo que le da un aspecto muy retro. Me gusta el resultado.
El rendimiento del ORIC es muy bueno en algunas cosas, como la impresión en pantalla, pero más flojo en otros aspectos, cosa que hacía que el juego no tirara con la fluidez que deseaba. Como todos los enemigos ocupan un único carácter, me he decidido a POKEar directamente en la pantalla de vídeo, en lugar de usar el PLOT. Esto ha simplificado el código y ha mejorado el rendimiento.
El bucle principal se repite hasta que perdemos la única vida de que disponemos. En cada pasada solo movemos uno de los enemigos, que se selecciona de forma aleatoria con un número entre 0 y 2:
1. Aleatoriamente hacemos subir o bajar la barrera de energía.
2. Aleatoriamente hacemos subir o bajar una de las tres naves enemigas.
3. Para los Fungaloids calculamos un número aleatorio grande. Si es inferior a 6, hacemos crecer el Fungaloid correspondiente y en caso contrario no hacemos nada. Esto hace que crezcan más lentamente, pero al ir avanzando en el juego, el número que calculamos disminuye y por consiguiente, aumentan su velocidad y la dificultad.
Para detectar colisiones, utilizo unas variables que indican la posición absoluta en la memoria de pantalla sobre la que está el ala izquierda de nuestra nave, o nuestro disparo. Accediendo a la memoria de video con un PEEK podemos ver que estamos tocando. Esto nos ahorra muchos cálculos, y es muy preciso.
En el juego original, al sobrevolar un Fungaloid nos disparaba. Aquí, para ganar velocidad he optado por hacer que nos dispare al destruir un fragmento de Fungaloid. Así aprovecho el mismo código que me indica que Fungaloid he alcanzado para poner su disparo en la planta correspondiente.
La verdad es que me habría gustado realizar algunas modificaciones, pero he optado por mantener el espíritu del juego original, y a pesar de estar programado completamente en BASIC, el juego ha conseguido una velocidad muy decente, y se deja jugar perfectamente. Eso si, mi cruz sigue siendo el sonido.
Os invito a probarlo