Curso de Jogos em Basic
Roteiro para implementar o jogo
Você está em: MarMSX >> Cursos >> Jogos em Basic
Nessa capítulo iremos formular um roteiro para a montagem final do jogo. Os principais pontos para a construção de um jogo no MSX foram vistos nos capítulos anteriores. Os demais pontos são mais simples de entender e serão discutidos nesse capítulo.
6.1. Inicialização
O primeiro passo a ser dado quando o jogo inicia é carregar na memória todos os dados necessários para o jogo funcionar, além de carregar os valores iniciais das variáveis do jogo.
Normalmente, um jogo precisa ao iniciar:
- Carregar na memória dados de sprites, tiles e outros dados auxiliares.
- Atribuir valores iniciais a algumas variáveis
- Carregar o código de rotina em linguagem de máquina (quando houver)
- Reservar área para código em linguagem de máquina (quando houver)
Sem essa preparação inicial, o jogo poderá falhar em sua execução. Onde estarão os sprites que a instrução PUT SPRITE chama? E o código em linguagem de máquina que roda a música? O herói começa no lugar certo do mapa?
6.2. Abertura
A abertura é onde você apresenta seu jogo. Uma animação bem feita na abertura pode cativar mais o jogador que o próprio jogo em si.
A abertura pode variar desde uma tela simples até a apresentação de ótimas animações. Quem não se lembra da abertura do jogo Alcatraz, onde tiros são disparados na tela em cima do título do jogo? E a do jogo Konami's Soccer, que o jogador caminha com a bola até o meio da tela e dá um chute nela?
Podemos fazer a tela de abertura em um editor gráfico, assim como utilizar os comandos de desenho do MSX para criar logos e figuras. Com uma certa habilidade, dá para fazer telas bonitas dessa maneira. Temos como exemplo o jogo Alcaltraz, a tela da Disprosoft e o jogo Lock-in Man da revista holandesa MSX Computer Magazine.
Para quem desejar incluir uma animação na abertura, dê uma olhada no capítulo anterior desse curso e no capítulo extra curso de Basic que fala sobre animações na screen 2.
6.3. Menu inicial
O menu principal é a parte do jogo que vem logo após a abertura. É nele onde você irá apresentar ao usuário os todos os recursos que você criou para ele.
Opções normalmente disponíveis:
- Jogar
- Teclado/Joystick
- Configuração de teclado/joystick
- Instruções
- Créditos
- Recordes
Recomenda-se fortemente que os recursos criados para o jogo, como por exemplo a configuração de teclado, sejam apresentados no menu principal. Senão, esses recursos deverão ser apresentados durante o fluxo de execução do jogo. De outra forma, o usuário não terá acesso a eles e sequer saberá que eles existem.
Normalmente o menu em jogos de MSX pode ser do tipo:
- Listagem com teclas de acesso para cada opção
- Menu com barra
O primeiro menu é uma lista de opções com uma tecla associada a cada opção. Foi largamente utilizado nos anos 80/90 pelos desenvolvedores. É o mais simples de se implementar. Exemplo:
Escolha uma opção:
T - Jogar com Teclado
J - Jogar com Joystick
I - Instruções
Construir um menu como esse é bastante simples. Devemos apenas imprimir o texto e colocar a instrução de captura de tela INKEY$. A instrução INPUT$(1) não é uma boa opção, pois deixa o cursor na tela.
10 SCREEN 0:WIDTH 40:COLOR 15,0,0
15 OP$="TtJjIi"
20 LOCATE 2,1:PRINT"Escolha uma opcao:"
30 LOCATE 2,3:PRINT"T - Jogar com Teclado"
40 LOCATE 2,4:PRINT"J - Jogar com Joystick"
50 LOCATE 2,5:PRINT"I - Instrucoes"
60 A$=INKEY$:IF A$="" THEN 60
70 OP = INT(INSTR(OP$,A$)/2 + .5) : 'Busca tecla entre as opções (OP$)
80 IF OP=0 THEN 60
90 ON OP GOSUB 200,210,220 : ' Se OP=1 vai p/ 200, se 2 p/ 210, se 3 p/ 220
100 GOTO 60
200 LOCATE 2,10:PRINT"Jogar com teclado selecionado":RETURN
210 LOCATE 2,10:PRINT"Jogar com joystic selecionado":RETURN
220 LOCATE 2,10:PRINT"Instrucoes: bla bla bla ":RETURN
O menu com barra consiste em uma listagem onde o usuário desliza uma barra/cursor pelas opções disponíveis, teclando espaço ou enter quando desejar acessar uma opção. Esse menu foi utilizado pelo Graphos III, Autoexec da Riosoft e nos jogos MarMSX. Veja os exemplos a seguir.
DesenhoPonto
Linha
Círculo
Raio
Esse tipo de menu é mais elegante, porém é bem complexo de construir nas screens 0 e 1 do MSX 1. Entretanto, no MSX 2 é bastante simples, pois há um recurso chamado blink que altera a cor de fundo dos caracteres, além de piscar em um intervalo programado.
Na screen 2, o trabalho de construção desse menu é facilitado, pois necessitamos apenas alterar a tabela de cores sob os caracteres que desejarmos. Veja o exemplo a seguir.
10 COLOR 15,0,0:SCREEN 2
20 OPEN"GRP:" AS #1
30 LINE(24,16)-(87,55),9,BF:LINE(24,16)-(87,23),6,BF
40 PRESET(26,16),9:PRINT#1,"Desenho"
50 PRESET(26,24),9:PRINT#1,"Ponto"
60 PRESET(26,32),9:PRINT#1,"Linha"
70 PRESET(26,40),9:PRINT#1,"Circulo"
80 PRESET(26,48),9:PRINT#1,"Raio"
90 OP=1:GOSUB 550
100 A$=INKEY$:IF A$="" THEN 100
110 A=ASC(A$)
120 IF A=30 THEN GOSUB 500:OP=((OP+2) MOD 4)+1:GOSUB 550
130 IF A=31 THEN GOSUB 500:OP=(OP MOD 4)+1:GOSUB 550
140 IF A=13 THEN SCREEN 0:END
150 GOTO 100
500 ' Rotina para limpar opcao
510 EI=8192+(OP+2)*256+24
520 FOR I=0 TO 63
530 VPOKE EI+I,&HF9
540 NEXT:RETURN
550 ' Rotina para marcar opcao
560 EI=8192+(OP+2)*256+24
570 FOR I=0 TO 63
580 VPOKE EI+I,&H9F
590 NEXT:RETURN
A mudança de cor feita em Basic é um pouco lenta. Além disso, a screen 2, devido às suas características, nos força a colocar a tabela e caracteres dentro de um grupo de 8x8 pixels.
Um menu feito em screen 0 pela Riosoft, uma loja que vendia produtos de MSX nos anos 80/90, é mais simples e possui bom desempenho.
┌───────────────────────────┐
│ RUNEXEC Vs 1.0 │
│ BY │
│ RIOSOFT INFORMATICA LTDA │
│ TEL. (021) 264-3726 │
└───────────────────────────┘
┌──────────────┬──────────────┐
│[PUCKY .BAS]│ RIOSOFT 1990 │
│ ALCATR .BAS │ RIOSOFT 1990 │
│ LOCKIN .BAS │ RIOSOFT 1990 │
│ DESTRU .BAS │ RIOSOFT 1990 │
│ BILOT .BAS │ RIOSOFT 1990 │
│ BALAO .BAS │ RIOSOFT 1990 │
│ HOUSE .BAS │ RIOSOFT 1990 │
│ ALIEN .BAS │ RIOSOFT 1990 │
│ SOCCER .BAS │ RIOSOFT 1990 │
│ VOLLEY .BAS │ RIOSOFT 1990 │
┌┴──────────────┼──────────────┴┐
│S - SISTEMA │B - MSX BASIC │
│N - NOVO DISCO │ENTER - EXECUTA│
├───────────────┴───────────────┤
│ Cursores movimentam colchetes │
└───────────────────────────────┘
A barra indicativa de opção nesse modelo é feita através dos colchetes "[" e "]" em torno da opção.
6.4. Instruções
Você teve um trabalhão para criar seu jogo e finalmente quando o público for ter acesso a ele, não sabe qual o objetivo do jogo e nem como controlar o personagem.
É por meio das instruções que você irá informar o público qual o objetivo geral do seu jogo, as regras dele, bem como quais os controles que você colocou a disposição dele para completar os objetivos.
Muitos jogos antigos de MSX vêm sem qualquer tipo de instrução, o qual torna um desafio jogá-lo. Por exemplo, em alguns dos jogos disponibilizados na seção Basic/Jogos tivemos que estudá-los para descobrir como jogar. Assim, disponibilizamos os objetivos gerais e os controles desses jogos na descrição da página.
O exemplo a seguir apresenta um modelo de instrução para um jogo no estilo Pac-man.
INSTRUÇÕES PARA O JOGO COMEDOR
Você é um pedaço de pizza que deverá percorrer
o labirinto, comendo todas as pastilhas e fugindo
dos fantasmas que o perseguem.
Você pode momentaneamente ficar imune aos fantas-
mas, quando comer as pastilhas redondas maiores.
Nesse caso, ao tocar os fantasmas, você ganha
pontos. Durante a imunidade da mesma pastilha, se
pegar os quatro fantasmas, ganhará um bônus extra.
Utilize as teclas do cursor para movimentar o
Comedor.
Além da descrição textual, você pode colocar desenhos com esquemas explicando o jogo, teclas etc. Veja o exemplo do Jogo da Senha.
6.5. Inicio do jogo e Loop principal
Passadas as etapas iniciais, podemos começar o jogo. Nesse momento é que iremos finalmente desenhar o cenário e preparar o jogo para iniciar.
Feita a preparação do cenário, o programa irá cair em um loop principal. É nesse loop que todas as ações do jogo serão controladas. Ações como:
- Controle de movimentos do jogador
- Controle de movimentos dos inimigos
- Controle de animações
- Controle de eventos do jogo
- Controle de eventos temporais
- Controle da música, se houver
A cada iteração ou passagem pelo loop, todas as ações/eventos necessários ao funcionamento do jogo deverão ser ativadas/verificados. Qualquer coisa que não seja incluída nesse trecho de código, o MSX deixará de executar.
O loop funciona como uma porta de entrada para disparar eventos contidos em outras sub-rotinas.
Cada ação/evento pode ser tratado no próprio loop principal ou desviar para outros trechos de código, desde que estes retornem ao menu principal ― uso de RETURN-GOSUB.
Nota importante: quando desviamos do loop principal para realizar alguma ação, não podemos ficar presos somente a essa ação, como por exemplo um loop para uma animação. Isso porque as ações comandadas pelo loop principal irão parar, e somente a ação do novo loop irá funcionar.
Nesse primeiro exemplo, disparamos uma bala "-" para acertar o alvo "*" com a barra de espaços.
10 SCREEN 0:KEY OFF
20 YA=0:XT=0
30 LOCATE XT,10:PRINT"-"
40 A=STRIG(0)
50 LOCATE 20,YA:PRINT"*"
60 IF A THEN 200
70 LOCATE 20,YA:PRINT" "
90 YA=YA+1:IF YA > 22 THEN YA=0
100 GOTO 40
200 ' Tratamento do disparo - loop
210 FOR XT=0 TO 39
220 LOCATE XT,10:PRINT"-"
230 LOCATE XT,10:PRINT" "
240 NEXT XT
250 LOCATE 0,10:PRINT"-"
260 GOTO 40
Assim que disparamos a bala, a animação do "*" pára para a bala se mover. Isso acontece porque o programa fica preso no loop das linhas 200-260. O jogo Chasse aux Poux (ou caça ao piolho) da revista francesa MSX Magazine possui esse problema.
No código a seguir, a animação da bala é controlada paralelamente à ação do "*".
10 SCREEN 0:KEY OFF
20 YA=0:XT=0:TD=0
30 A=STRIG(0)
40 IF A THEN TD=1
50 LOCATE 20,YA:PRINT"*"
60 LOCATE XT,10:PRINT"-"
80 LOCATE 20,YA:PRINT" "
90 YA=YA+1:IF YA > 22 THEN YA=0
100 IF TD=1 THEN LOCATE XT,10:PRINT" " : XT=XT+1
110 IF XT>39 THEN XT=0 : TD=0
120 GOTO 30
Agora a bala e o "*" movem juntos na tela.
Alguns eventos podem ser controlados pelo próprio MSX em vez do loop principal. Por exemplo, através do uso da instrução ON INTERVAL GOSUB, onde o MSX se torna responsável pelo monitoramento de um evento. O mesmo se aplica para músicas, onde podemos criar uma rotina em linguagem de máquina para executar a música, utilizando o mecanismo de hooks para controlar a atualização da música.
Obs: os eventos temporais também podem ser feitos dentro do loop principal através da contagem de tempo, utilizando-se a variável de sistema TIME.
O capítulo 17 do curso de Basic também fala sobre eventos e como tratá-los.
6.6. Fim de jogo - bom ou ruim
Quando o jogador completa uma missão no jogo ou perde em definitivo, o programa deve desviar em definitivo do loop principal para uma rotina que irá tratar o evento correspondente. No caso do jogador terminar uma fase, deve-se chamar uma rotina para desenhar o próximo cenário e retornar ao menu principal.
As rotinas de sucesso/fracasso podem ou não conter animações. Entretanto, é muito comum nessa hora divulgar o placar final do jogador, bem como a comparação de sua pontuação com os recordes do jogo.