Obrigado a Julio Marchi pelo espaço cedido na MSX All
 

Curso de Jogos


 

Guie o Balão

English


1. Introdução
  O objetivo do jogo é guiar um balão por um labirinto até uma cruz preta localizada no alto da tela.
  Guie o Balão foi publicado na revista MSX Micro número 4 e é bastante simples de entender a lógica do jogo, principalmente para aqueles que estão começando a criar jogos.

Requisitos:

- MSX 1


2. Estrutura do jogo
  O jogo foi desenvolvido em Basic para MSX 1, onde alterna entre a screen 0 para textos e mensagens, e screen 2 para o jogo em si.
  O balão é desenhado através de um sprite de 8x8 pixels no modo pequeno.
  Há quatro sub-rotinas para desenhar cada tela, onde cada uma utiliza o comando DRAW para desenhar os obstáculos do balão.
  O loop principal utiliza o comando STICK para aguardar o jogador teclar algo ou mover o joystick, de forma a controlar o balão. Além disso, utiliza um retângulo envoltório para analisar o espaço que o balão está passando (espécie de teste de colisão).
  O jogo se baseia nas seguintes informações da tela para tomar suas decisões: se o local onde o balão está passando sobre for vermelho, perde-se uma vida e recomeça a tela. Se o local for preto, a missão foi cumprida e passa-se para a tela seguinte. Caso seja diferente dessas cores, prossiga com o jogo.


3. Código do jogo comentado
  Inicializações gerais e variáveis do jogo

  Variáveis utilizadas:
  • Q - define: 0=teclado, 1=joystick.
  • S - número da tela atual.
  • LI - número de vidas do jogador.
  • SC - pontuação do jogador.
  • HI - maior pontuação obtida.
10 COLOR1,15,15:KEYOFF:HI=0:PLAY"O2G#F#BO3C#GD#C#F#D#O2BC#C#F#":
Q=0:GOSUB1300:OPEN"GRP:"AS#1:N$="M S X"
20 LI=3:S=1:CLS:SC=0
30 SCREEN 2,0


  Desenho do balão

40 RESTORE:A$="":FORF=0TO7:READD$:A$=A$+CHR$(VAL("&B"+D$)):NEXTF:SPRITE$(0)=A$
50  DATA 00001000
60  DATA 00011100
70  DATA 00111110
80  DATA 00111110
90  DATA 00010100
100 DATA 00010100
110 DATA 00011100
120 DATA 00011100


  Sub-rotinas para desenho das telas

  A sub-rotina a seguir é responsável por desenhar os elementos em comum das quatro telas, bem como gerenciar as demais sub-rotinas de desenho da tela.
130 ' ** TELA **
140 TIME=0
150 CLS
160 GOSUB1910
170 ONSGOSUB380,530,680,830,1140
180 DRAW"BM230,11C1R10D10L10U10F10L10E10"
190 COLOR15:PRESET(10,3):PRINT#1,"VIDAS=";LI:PRESET(10,180):PRINT#1,"PONTOS=";SC
  O primeiro passo é zerar o tempo, de forma a medi-lo quando o jogador completar a tela (linha 140). Em seguida, é chamada uma sub-rotina na linha 1910 para desenhar as bordas, que são comuns à quatro telas.
1910 LINE(0,0)-(250,10),6,BF
1920 LINE(0,0)-(10,190),6,BF
1930 LINE(250,0)-(240,190),6,BF
1940 LINE(0,190)-(250,180),6,BF
1950 RETURN
  A linha 170 cria uma ordem de chamadas às sub-rotinas de cada tela, mais a sub-rotina de fim de jogo (linha 1140), de acordo com o valor de S, que é a tela atual.
  A linha 180 desenha o "X" preto no canto superior direito da tela, através do comando DRAW. O código C1 indica a cor 1 para o "X".
180 DRAW"BM230,11C1R10D10L10U10F10L10E10"
  A linha 190 escreve os dados na tela, como número de vidas restantes e o total de pontos.


  Tela 1

380 ' ** TELA 1 **
390 A$="E10F10H5G5"
400 LINE(0,100)-(100,108),6,BF:LINE(111,100)-(250,108),6,BF
410 LINE(111,0)-(119,30),6,BF:LINE(111,43)-(119,100),6,BF
420 DRAW"BM84,70C6XA$;"
430 FORT=30TO200STEP20
440 DRAW"BM=T;,165C6XA$;"
450 NEXTT
460 DRAW"BM70,50C6XA$;"
470 DRAW"BM18,68C6XA$;"
480 DRAW"BM18,60C6XA$;"
490 DRAW"BM220,40C6XA$;":DRAW"BM122,50C6XA$;":DRAW"BM142,40C6XA$;"
500 DRAW"BM165,33C6XA$;"
510 X=150:Y=130
520 RETURN
  A linha 390 define em A$ o seguinte obstáculo, que será desenhado pelas linhas 420, 440 e 460-500:



  Traduzindo o conteúdo de A$, temos os seguinte movimentos:
10↗, 10↘, 5↖, 5↙
  Cada uma das linhas citadas anteriormente que utiliza o A$, faz o seguinte:
BM X,Y - Define a coordenada inicial do desenho.
Cn - Define a cor do desenho, que é 6 (vermelho).
  Na linha 510, define-se a posição inicial do balão.


  Tela 2

530 ' ** TELA 2 **
540 B$="R10H5G5D10R4U4R2D4R4U10D10L10"
550 FORT=30TO230STEP11
560 DRAW"BM=T;,50C6XB$;"
570 NEXTT
580 FORT=10TO220STEP11
590 DRAW"BM=T;,100XB$;"
600 NEXT
610 FORT=30TO230STEP11
620 DRAW"BM=T;,145XB$;"
630 NEXT
640 X=220:Y=160
650 DRAW"BM109,78XB$;":DRAW"BM130,70XB$;":DRAW"BM160,78XB$;"
660 DRAW"BM109,128XB$;":DRAW"BM130,120XB$;":DRAW"BM160,128XB$;"
670 RETURN
  O princípio é o mesmo da tela 1, porém o obstáculo é diferente e é definido em B$:





  Tela 3

680 ' ** TELA 3 **
690 LINE(30,50)-(45,190),6,BF
700 DRAW"BM32,25C6XB$;"
710 LINE(60,0)-(75,147),6,BF
720 DRAW"BM62,165XB$;"
730 LINE(90,50)-(105,190),6,BF
740 DRAW"BM92,25XB$;"
750 LINE(120,0)-(135,147),6,BF
760 DRAW"BM122,165XB$;"
770 LINE(150,50)-(165,190),6,BF
780 DRAW"BM152,25XB$;"
790 LINE(200,0)-(230,100),6,BF
800 LINE(200,112)-(215,190),6,BF
810 X=15:Y=150
820 RETURN
  Essa tela utiliza o mesmo obstáculo que a tela 2.


  Tela 4

830 ' ** TELA 4 **
840 LINE(120,0)-(126,60),6,BF
850 X=200:Y=160
860 LINE(120,72)-(126,135),6,BF
870 LINE(120,147)-(126,190),6,BF
880 LINE(0,90)-(70,96),6,BF
890 LINE(80,90)-(250,95),6,BF
900 C$="U10R12U5R3D15L15"
910 DRAW"BM90,62XC$;"
920 DRAW"BM97,35XC$;"
930 DRAW"BM78,82XC$;"
940 DRAW"BM73,57XC$;"
950 DRAW"BM200,140XA$;"
960 DRAW"BM185,130XA$;"
970 DRAW"BM157,140XA$;"
980 DRAW"BM215,135XA$;"
990 DRAW"BM132,151XA$;"
1000 FORT=20TO115STEP11
1010 DRAW"BM=T;,156XB$;"
1020 NEXT
1030 DRAW"BM82,105XB$;"
1040 DRAW"BM60,105XB$;"
1050 DRAW"BM73,132XB$;"
1060 D$="U30R10D30L10U26BR3R3D3L3U3BD5R3D3L3U3BD5R3D3L3U3BD5R3D3L3U3BD5R3D3L3U3"
1070 DRAW"BM220,78XD$;"
1080 DRAW"BM205,46XD$;"
1090 DRAW"BM136,45XD$;"
1100 DRAW"BM136,87XD$;"
1110 DRAW"BM157,67XD$;"
1120 DRAW"BM188,82XD$;"
1130 RETURN
  A tela mais difícil, além de apresentar dois novos obstáculos, definidos em C$ e D$, respectivamente:

  e  


  Missão cumprida

1140 ' ** FIM DO JOGO **
1145 ' ** VOLTA P/ O INICIO **
1150 SCREEN 0:COLOR1
1160 CLS
1170 PRINT"     PARABENS, BALONISTA ! VOCE"
1180 PRINT
1190 PRINT"     COMPLETOU TODAS AS TELAS !"
1200 PRINT
1210 PRINT"     SEUS PONTOS FORAM :"
1220 PRINT
1230 PRINT"     ";SC
1240 PRINT
1250 PRINT"     PRESS. ESPACO OU TIRO"
1260 PRINT
1270 PRINT"     PARA A PROXIMA JORNADA."
1280 S=1:IFSTRIG(Q)THENSCREEN2,0:GOTO40
1290 GOTO 1280
  Caso as quatro telas sejam completadas com sucesso, uma mensagem é impressa na screen 0. A linha 1280 aguarda a barra de espaços ou o tiro do joystick serem acionados pare recomeçar o jogo.


  Loop principal

  Rotina responsável por analisar os comandos do jogador e o que se passa na tela.
200 ' ** LOOP PRINCIPAL **
210 ST=STICK(Q):IFST=0THEN250
220 IFST=1THENY=Y-1:GOTO 260
230 IFST=3THENX=X+1:GOTO 260
240 IFST=7THENX=X-1:GOTO 260
250 Y=Y+1
260 PUTSPRITE0,(X,Y),3
270 IFPOINT(X,Y)=6THENGOTO 330
280 IFPOINT(X,Y)=1THENGOTO 360
290 X%=X+7:Y%=Y+8
300 IFPOINT(X%,Y%)=6THENGOTO 330
310 IFPOINT(X%,Y%)=1THENGOTO 360
320 GOTO210
  As linhas 210-250 são responsáveis por analisar os comandos de teclado ou joystick do jogador. Essa rotina analisa somente os movimentos para cima (ST=1), direita (ST=3) e esquerda (ST=7). Quando qualquer outra tecla é pressionada, ou até mesmo quando nenhuma tecla é pressionada, o balão cai (linha 250).
  De forma a melhorar o controle do balão, sugere-se acrescentar as seguintes linhas que tratam os dois movimentos diagonais para cima:
225 IFST=2THENY=Y-1:X=X+1:GOTO 260
245 IFST=8THENY=Y-1:X=X-1:GOTO 260
  A linha 260 é responsável por desenhar o balão na tela.
  As linhas 270-310 criam um retângulo envoltório (bounding box) em torno do balão, para analisar a região que o balão está passando.
  Na ilustração a seguir, o retângulo é definido pela área delimitada pelas cruzes "+".
+
   1   
  111  
 11111 
 11111 
  1 1  
  1 1  
  111  
  111+
  Apesar de definir um retângulo, a rotina testa somente as cores dos pixels localizadas exatamente nas coordenadas das cruzes. O teste pode ser mais completo, testando-se as coordenadas dos outros dois pontos do retângulo.
  Em cada teste, verifica-se se o ponto é vermelho, que é a falha e, conseqüentemente, a perda de uma vida:
330 LI=LI-1:IFLI<1THEN1710
340 PLAY"O4L5CCCD#DDCCCC":FORT=1TO100:NEXTT
350 GOTO130
  Ou preto, que é o sucesso:
360 IFTIME<3000THENSC=SC+3000-TIME
370 PLAY"O6DB":S=S+1:GOTO 130
  Na linha 360, mede-se o tempo gasto para completar a tela, que serve de base para calcular a pontuação.
  O valor 3000 para o TIME corresponde a 30 segundos para completar cada tela. É um valor pequeno para as telas 2-4, o que acarreta geralmente em uma pontuação nula para elas.


  Tela inicial

1300 COLOR1:CLS
1310 PRINT"           GUIE O BALAO":PRINT
1320 PRINT:PRINT:PRINT:PRINT:PRINT
1330 PRINT" "
1340 PRINT
1350 K$="     'D' P/ VER TELAS "
1360 X$="GUIE O BALAO ...........'C' P/ COMECAR.........'J' 
P/ JOYSTICK.........'I' P/ INSTRUCOES."
1370 COLOR1:J$=K$+X$
1380 FORT=1TOLEN(J$)
1390 LOCATE4,15:PRINTTAB(2);MID$(J$,T,18)
1400 LOCATE4,15:FORK=1TO100:NEXT
1410 A$=INKEY$:IFA$=""THENNEXT
1420 IFA$="C"THENRETURN
1430 IFA$="J"THENQ=1
1440 IFA$="I"THEN1470
1450 IFA$="D"THEN1960
1460 GOTO1380
  As linhas 1350-1400 criam um texto corrido na tela, assim como o comando MID$ no livro de Basic do Expert [1].
  As linhas 1410-1450 esperam uma tecla ser pressionada. Repare que somente as letras maiúsculas são tratadas, o que resulta na não captura das letras minúsculas. Elas podem ser alteradas para a seguinte configuração, de forma a sanar o problema:
1420 IFA$="C"ORA$="c"THENRETURN
1430 IFA$="J"ORA$="j"THENQ=1
1440 IFA$="I"ORA$="i"THEN1470
1450 IFA$="D"ORA$="d"THEN1960


  Instruções

1470 CLS
1480 PRINT"        GUIE O BALAO
1490 PRINT
1500 PRINT"   SEU BALAO ESTA FURADO E VOCE"
1510 PRINT"   PRECISA VIAJAR ATRAVES DE "
1520 PRINT"   QUATRO TELAS DE SUSPENSE"
1530 PRINT"   PARA CONTINUAR NO AR"
1540 PRINT
1550 PRINT"   PARA COMPLETAR A TELA VOCE"
1560 PRINT"   PRECISA POUSAR NA CRUZ"
1570 PRINT"   NEGRA NO TOPO DIREITO"
1580 PRINT"   DA TELA":PRINT
1590 PRINT"   TOCANDO EM QUALQUER COISA"
1600 PRINT"   RESULTA NA PERDA DE UMA "
1610 PRINT"   VIDA":PRINT
1620 PRINT"   CUIDADO ! O BALAO INICIA"
1630 PRINT"   CAINDO QUANDO A TELA"
1640 PRINT"   E' DESENHADA.":PRINT
1650 PRINT"   BOA SORTE!
1660 PRINT
1670 PRINT"   -PRESS. ESPACO-"
1680 A$=INKEY$:IFA$=""THEN1680
1690 IFA$<>" "THEN1680
1700 CLS:GOTO 1380


  Rotina para mostrar as telas

1960 SCREEN2,0:CLS:D=1
1970 ONDGOSUB380,530,680,830
1980 IFD=5THENFORT=1TO1000:NEXT:CLS:SCREEN0:GOTO1380
1990 GOSUB1910:D=D+1:FORT=1TO1000:NEXT:CLS:GOTO1970


  Fim do jogo

1710 COLOR1:SCREEN0
1720 CLS:PRINT"    VOCE BATEU MAS SEUS PONTOS SAO :"
1730 PRINT:PRINT
1740 PRINT"              ";SC
1750 IFSC>HITHENGOSUB1850
1760 PRINT:PRINT
1770 PRINT"        O RECORDE AGORA E:"
1780 PRINT:PRINT
1790 PRINT"            ";HI
1800 PRINT:PRINT"     POR:- ";N$
1810 PRINT:PRINT"   PRESS. 'C' PARA JOGAR NOVAMENTE"
1820 A$=INKEY$:IFA$=""THEN1820
1830 IFA$="C"ORA$="c"THENGOTO 20
1840 GOTO 1820
1850 PRINT"     UM NOVO RECORDE !":PRINT
1860 PRINT"DIGITE SEU NOME: ":PRINT
1870 LINEINPUTN$
1880 IFLEN(N$)>15THENPRINT:PRINT"MUITO LONGO":GOTO 1860
1890 HI=SC
1900 RETURN


4. Versão MSX 2

  Aproveitando os recursos do MSX 2, resolvi melhorar os gráficos do jogo, bem como sanar alguns problemas existentes no jogo.

  Melhorias:
  • Gráficos de screen 2 para screen 5.
  • Sprites modo 2 para o balão.
  • Desenho da tela em pano de fundo.
  • Aceita movimentos em diagonal para cima.
  • Letras minúsculas capturadas no menu inicial.
  • Armazena até 5 recordes, que são gravados em disco.
  Veja os comentários das mudanças aqui.


5. Download
  Jogo completo: Guie o Balão.
  Jogo convertido para MSX 2: Guie o Balão 2.



  Referências:

  [1]- Livro Linguagem Basic, 5a. Edição, P. Piazzi, Editora Aleph, 1987.


Marcelo Silveira
Engenheiro de Sistemas e Computação
Especialista em Processamento de Imagens e Inteligência Artificial
© MarMSX 1999-2023