aula
2 - versão 1.0 para Visual Basic - 08 setembro
2000
Tutorial:
Noções Básicas de Programação de Jogos
endereço atual:
http://www.oocities.org/victormsantanna/
Acerte os ponteiros do seu timer
Victor
M. Sant'Anna
Introdução
Criamos uns brinquedos
na lição anterior, mas o que poderíamos fazer
para transformá-los em jogos? Uma bola é
um brinquedo, por exemplo. Futebol, vôlei,
basquete e pingue-pongue são jogos. Qual a
diferença? Simuladores de vôo são
brinquedos. Sim City é mais brinquedo do
que jogo (Sim City tem objetivos, mas
geralmente não jogamos com as regras do jogo,
ficamos brincando de construir cidades com o
programa). Blocos de madeira e areia
podem ser brinquedos, mas podemos criar um jogo
estabelecendo regras e objetivos, como, por
exemplo: "quem criar o castelo mais alto em
5 minutos ganha o jogo". Frescobol é um
jogo? Não tem regras muito fixas (exceto,
talvez: "não pode deixar a bola
cair"), o objetivo é pouco definido e
ninguém ganha... Essa aí é para pensar em
casa!
Um bom programa
não precisa ser um jogo, pode ser um brinquedo,
mas é bom ter sempre em mente essas pequenas
diferenças. Geralmente o jogo tem
situações de vitória e derrota,
para começar. Podemos começar por aí e criar
nossos primeiros jogos.
Vamos aproveitar o
que vimos na lição anterior e ver como proceder
para criar um jogo acrescentando um Timer
em um form. A situação é bem simples,
uma série de controles (podem ser botões ou
caixas de figura) estará desativada e um Timer
ativará um dos controles aleatoriamente. Esses
controles poderiam ser botões, por exemplo, mas
vamos fazer o mesmo com figuras, para mostrar
como poderíamos construir um jogo um pouco mais
elaborado.
Botões nervosos
Para aproveitar a
função rnd() vista na lição anterior,
vamos ativar um controle (um botão, em nosso
exemplo) a cada vez que o Timer for
chamado. A idéia do Timer é simples,
escolhemos um valor em milissegundos para a
propriedade Interval e isso faz com que, a
cada intervalo de tempo escolhido, o código
posicionado dentro de Timer_Timer() seja
realizado. Vamos lá:
1) Crie um projeto
novo e coloque, no form1 criado, um botão
(CommandButton);
2) Selecione o
botão criado e modifique (através da caixa de
propriedades, a janela properties) a
propriedade Enabled para False;
3) Mude a
propriedade caption para
"Aperte-me";
3) Dê um
"copiar" (copy) nesse botão
(selecione-o e use Ctrl-C, por exemplo).
4) Cole no form
o botão copiado (pode usar Ctrl-V, por exemplo):
o Visual Basic pergunta se você quer criar um
"array" de botões, responda que sim.
Assim poderá ativá-los pelo índice de cada
botão.
5) Repita o passo
anterior até ter 10 botões.
6) Espalhe os
botões pelo form.
7) Adicione um timer
ao form (tem a forma de um relógio). Não
faz diferença onde é colocado, já que fica
invisível em tempo de execução. Mude seu valor
de intervalo (Interval) para 800 ou 900.
Depois você vai querer reajustar isso, mas esses
valores estão bons para iniciar.
Devemos ter agora
no form criado vários botões:

8) Dê um duplo
clique em um dos botões de comando para inserir
as linhas de código que permitem somar os pontos
do jogador. O código deve ficar assim:
Private Sub
Command1_Click(Index As Integer)
placar
= placar + 1
End Sub
|
9) Precisamos de
uma variável para guardar os pontos feitos pelo
jogador. Já que a variável placar
precisa ser "zerada" para o início da
partida, é melhor declará-la na seção de
declarações de nosso form. Vamos fazer as duas
coisas, zerar a variável em Form_Load() e
declarar a variável na seção declarations
de general. Você pode fazer isso dando um
"duplo clique" no form ou indo
na janela de projeto (onde está escrito Project1)
e apertar o botão onde diz View Code:
Deve surgir a
janela de código de form1:
a) Nesta janela,
vamos aproveitar e acrescentar o comando
randomize visto na lição anteior. Também
vamos, embora não seja necessário,
"zerar" a variável sempre que o jogo
iniciar e "zerar" o marcador de
duração da partida. Acrescente em Form_Load()
as linhas:
Randomize placar = 0
tempodojogo
= 0
|
A janela fica
assim:

b) Onde está
escrito Object: Form na janela acima,
procure e troque por "(General)".
Escreva a declaração das variáveis placar e
tempodojogo como variáveis do tipo inteiro:
Dim placar As Integer
Dim
tempodojogo As Integer
|
No Visual Basic
existe uma opção - option explicit
- que obriga as variáveis de serem declaradas
obrigatoriamente, mas não estamos utilizando
essa opção, por isso outras variáveis usadas
no programa não estão sendo declaradas aqui.
Por uma questão de clareza, estilo e segurança,
na verdade todas as variáveis deveriam ser
declaradas (embora não de forma global, como
fizemos aqui).
A seção de
declarações deve ficar algo como a tela abaixo:

10) Vamos
acrescentar agora o código do timer. Dê
um "duplo clique" no desenho do timer
que está no form (ou troque general
por timer1 como visto acima). Acrescente o
seguinte código em Timer1_Timer():
For i = 0 To 9 Command1(i).Enabled
= False
Next i
MyValue =
Int(10 * Rnd) ' Generate random value
between 0 and 9.
Command1(MyValue).Enabled
= True
tempodojogo
= tempodojogo + 1
If
tempodojogo > 30 Then
MsgBox
("total = " + Str$(placar) +
" acertos")
End
End If
|
11) Teste tudo,
não esquecendo de salvar o programa antes de
rodar. Agora você tem um programa que é
um jogo.
12) Embeleze o
programa
a) modificando o
nome do form de form1 (propriedade Caption)
para outro nome mais interessante (como
"Aperte-me outra vez"),
b) alterando o
ícone do form (propriedade icon)
por algum outro. Algo como:
c) acrescentando
em algum lugar uma caixa de texto (Text1.Text)
para mostrar o placar enquanto jogamos: basta
acrescentar, dentro do código do botão, logo
depois do código atual, um comando fazendo a
caixa de texto ter o valor de placar. Por
exemplo:
placar = placar + 1 Text1.Text = placar
|
13) Crie o
executável.
Eis o resultado:

Problemas nos "apertões"
Se você testar o
programa, vai notar que o uso de botões é, em
termos de "jogabilidade" horrível
(além de ser esteticamente desastroso), pois o
programa "rouba": mesmo quando temos
certeza que "clicamos" no botão a
tempo, o placar não mostra isso! O que está
acontecendo?
É simples: a
função Click() usada nos botões exige
"cliques" bem definidos - parar o mouse
em cima do botão antes de "clicar".
Ora, isso quer dizer que se o mouse está em
movimento, um "clique simples" não
será aceito pelo Windows. Você pode testar isso
movendo o ponteiro do mouse em alguma
outra aplicação e tentando "clicar"
os botões com o mouse em movimento: eles
não executarão o comando! Isso é péssimo,
não acha?
Vamos consertar
isso simplesmente recortando o código que está
em Command1_Click() e jogando o código em
Command1_MouseDown(). Isso deverá
resolver o problema, mesmo não identificado como
"clique", apertar o botão do mouse
fará que a rotina "pegue" o nosso
"abaixar" de botão. Para isso,
a) vá em Command1_Click(),
selecione todo o código que está lá (devem ser
só duas linhas) e "recorte" o código
(Ctrl-X pelo teclado ou, no menu Edit,
opção cut do Visual Basic)
b) na janela onde
está escrito Proc:Click troque
para Proc:MouseDown: você estará
saindo da subrotina Command1_Click() e
entrando na rotina Command1_MouseDown()

c) cole o código
anterior (pode usar Ctrl-V) aí, deixando assim:
Private Sub
Command1_MouseDown(Index As Integer,
Button As Integer, Shift As Integer, X As
Single, Y As Single)
placar
= placar + 1
Text1.Text
= placar
End Sub
|
Teste o programa.
Escolha valores melhores para a propriedade Interval
do timer1 e pronto! Salve tudo e crie o
executável, tratando de embelezar o programa com
ícone e nome mais adequado.
Coitado do chefe
Agora que o
programa está funcionando, tente imaginar o que
deve mudar para transformá-lo em um programa que
simula o lançamento de tortas (ou outra coisa de
sua preferência como ovos ou tomates) na cara do
seu chefe, de sua sogra ou de algum amigo (futuro
ex-amigo). Pode presentear alguém com um jogo
personalizado. Dica: se você não sabe
desenhar, existem desenhistas que fazem
caricaturas a partir de fotos, já vi em diversos
shopping-centers. Alguns trocados e um scanner
ajudarão você a fazer um presente
inesquecível... vamos lá!
Vou supor que
nosso alvo seja um ursinho (emprestado da minha
filha) saindo de uma caixa. Capturei ele na minha
câmera de vídeo que usa a porta paralela (não
é grande coisa, mas já serve, se você não
sabe desenhar). Vamos precisar de uma figura para
o urso escondido, uma dele de cara limpa, saindo
da caixa e uma do urso de cara lambuzada (não
foi difícil alterar a anterior no Paint
para parecer suja, embora o resultado esteja com
cara de trabalho amador). Poderíamos ter mais
uma figura dele furioso depois de ser atingido
(para dar um toque de humor), mas para começar,
3 está ótimo. Se for bom artista ou fotógrafo,
talvez queira mais do que 3 imagens, vamos montar
o básico e o resto é com você. Aqui estão as
imagens:

1) Começando um
novo projeto, modifique a cor de fundo do form
(propriedade BackColor) para a cor de
fundo do seu desenho. No nosso caso, a área ao
redor da caixa do ursinho é branca, portanto
branco será a cor de fundo de nossa janela.
2) Adicione uma
caixa de figura (PictureBox1). Selecione e
copie a caixa de figura e modifique (através da
caixa de propriedades)
a) sua propriedade
AutoSize para True e
b) a propriedade Visible
para False.
3) Dê um
"copiar" (copy) nessa caixa de figura.
4) Cole no form
a caixa de figura copiada (PictureBox1): o
Visual Basic pergunta se você quer criar um
"array" de caixas de texto (array
control), responda que sim. Queremos
ter um array com 3 caixas de figura, portanto
repita o "colar" até ter as 3 caixas
de figura. Cuidado para não colar as caixas de
figura dentro umas das outras, mas sim no form
criado. A posição não importa, essas caixas de
figura serão invisíveis em tempo de execução.
Devemos ter agora
no form 3 caixas de figuras (Picture1(0)
a Picture1(2)), mais ou menos assim:
5) Cole as imagens
do urso (ou leia os bitmaps através da
propriedade Picture) em cada caixa de
figura. O que faremos: deixaremos essas caixas de
figura invisíveis em tempo de execução e
copiaremos seu conteúdo para outra caixa de
figura durante o jogo. A picture1(0) será
a figura da "caixa sem o ursinho", a picture1(1)
será a do "ursinho aparecendo" e a picture1(2)
será a do "ursinho atingido".
6) Adicione uma
nova caixa de figura (PictureBox2) ao form.
7) Selecione e
copie a caixa de figura criada no passo anterior
(PictureBox2) e certifique-se (através da
caixa de propriedades) que
a) sua propriedade
AutoSize seja True,
b) sua propriedade
Appearance seja mudada para "0 - flat"
c) sua propriedade
BorderDtyle seja mudada para "0 - None"
e
d) a propriedade Visible
também seja True (esse já é o valor default).
As mudanças acima
são para que as imagens não tenham bordas, mas
você pode preferir diferente no seu programa.
8) Apenas para
facilitar o posicionamento, carregue a figura do
ursinho (propriedade Picture) nessa caixa
de texto (PictureBox2), ou cole como fez
anteriormente com a PictureBox1. Isso
fará com que essa caixa de figura tenha o
tamanho exato que terá quando o jogo estiver em
funcionamento.
9) Selecione e dê
um "copiar" (copy) nessa caixa de
figura.
10) Cole no form
a caixa de figura copiada: o Visual Basic
pergunta se você quer criar um "array"
de caixas de texto (array control),
responda que sim. Queremos ter um array
com 10 caixas de figura: repita o
"colar" até ter as 10 caixas de
figura.
11) Posicione
cuidadosamente as caixas de figura recém coladas
(PictureBox2). Essas são as caixas que
serão visíveis. Centralize-as e ajuste a janela
do form para deixá-las bem enquadradas.
Não se preocupe com a posição das figuras que
ficarão invisíveis (PictureBox1).
Teremos algo como:

12) Acrescente um
controle Timer. Modifique sua propriedade
Interval para 600 milissegundos.
13) Vamos ao
código... Usaremos quase que o mesmo código que
no programa anterior, apenas não usaremos as
propriedades enabled da caixa de figura,
mas, em seu lugar, carregaremos a figura do
ursinho escondido na caixa. Para isso, dê um
"duplo clique" no controle Timer
colocado no form e acrescente o código
seguinte em Timer1_Timer():
For i = 0 To
9 Picture2(i).Picture
= Picture1(0).Picture ' deixa ursinho
escondido
Next i
MyValue =
Int(10 * Rnd) ' Generate random value
between 0 and 9.
Picture2(MyValue).Picture
= Picture1(1).Picture ' aparece o ursinho
tempodojogo
= tempodojogo + 1
If
tempodojogo > 30 Then
MsgBox
("total = " + Str$(placar) +
" acertos")
End
End If
|
14) Dê um duplo
clique em uma das caixas de figura do ursinho (PictureBox2)
no form. Deve surgir uma janela como essa:

Pelas mesmas
razões do programa anterior, não queremos
colocar código no evento click, mas no
evento Mouse_Down(). Portanto, modifique Proc:Click
da janela acima para Proc:MouseDown.
Acrescente então o seguinte código em Picture2_MouseDown():
If Index = MyValue Then
placar =
placar + 1
Picture2(Index).Picture
= Picture1(2).Picture
End If
|
Já que a
propriedade enabled não está sendo
usada, diferentemente de nosso projeto anterior,
todas as figuras estarão habilitadas para
receber um "clique". Por isso tivemos
de controlar os "cliques" corretos
através de uma variável (MyValue) que
diz quando um "clique" na caixa de
figura é válido para contagem de pontos. Sem
isso, um "clique" em qualquer caixa de
figura, mesmo com o ursinho escondido, seria
considerado um acerto! Usamos a variável MyValue,
porque o índice da caixa de figura que
corresponde ao ursinho que está aparecendo foi
guardado nessa variável, lá em Timer1_Timer().
O único detalhe é que a variável MyValue
não havia sido declarada (era uma variável
local) e agora precisará de uma declaração.
15) Colocamos
diversas variáveis no programa mas ainda não as
declaramos nem as inicializamos, portanto vamos
fazer isso agora. Na seção de declarações de form1,
exatamente como no programa anterior (seção
"(general)", "declarations"),
coloque o código:
Dim placar As Integer
Dim
tempodojogo As Integer
Dim
MyValue As Integer
|
16) Em Form_Load()
coloque a sentença Randomize e
inicialização das variáveis:
Randomize placar = 0
tempodojogo
= 0
MyValue =
0
|
16) Salve e teste
o programa. Se estiver tudo certo, mude nomes dos
botões, do formulário e mude o ícone, salvando
tudo outra vez. O ícone poderá ser esse:
17) Crie o
executável.
O programa deve
ter ficado mais ou menos assim:

Conclusão
Existem várias
coisas que podem ser adicionadas aqui, mas isso
agora é com vocês (a mais simples seria
adicionar som quando atingimos o ursinho, mas
ainda não sabemos fazer isso).
Com esse código,
programas do tipo "atire no bandido
escondido", poderão ser realizados
facilmente, bastando construir um cenário
elaborado e digitalização de atores aparecendo
nas posições corretas. Você pode criar
personagens que não devam ser atingidos
(diminuindo ou "zerando" o placar, por
exemplo), entre outras coisas. Divirta-se
criando!
Algo importante a
ser observado, é que ainda não estamos usando
movimento de objetos (apenas controles
estáticos), mas já dá para ter uma idéia de
como um jogo pode ficar mais animado mesmo quando
não utilizamos "movimento": o simples
fato de trocarmos as imagens estáticas (como no
jogo dos botões) por imagens trocadas
sucessivamente, já dão um aspecto bem mais
dinâmico ao programa!
|