Cenário giratório
periscopando
em volta do submarino
O pessoal da velha guarda deve se lembrar,
principalmente os "ratos" de fliperama, de uma máquina que vivia
cheia de gente, onde era comum esperar horas pela vez de jogar. Um periscópio,
uns naviozinhos ao fundo e umas luzes seqüenciais, para simular
o torpedo. Lá pelo final dos anos 60, início dos 70.
Em Santos, no litoral de São Paulo,
havia uma máquina particularmente especial: gigantesca, envidraçada
em três lados, ocupava quase todo o centro do fliper. Disputadíssima,
passava a maior parte do tempo "em manutenção". Mas só
de olhar para ela a imaginação disparava.
No que se refere a mar e batalha naval,
talvez nada supere o máximo em espírito de aventura do
que comandar um submarino. Principalmente um daqueles da segunda guerra
mundial, quando ainda não contavam com instrumentos sofisticados,
mísseis nucleares ou propulsores turbinados.
Na era do computador multimídia,
não poderiam faltar os simuladores de submarino. E eles existem,
é claro. Mas é certo também que se tornaram tão
fiéis à realidade, mas tão fiéis, que se
transformaram em jogos chatos. Lembro de ter lido há algum tempo,
numa revista inglesa, uma crítica a um desses simuladores. O
articulista perguntava porque não havia aquele clássico
som do sonar, no jogo.
Os técnicos explicaram então
que tal som não existe. Que é uma invenção
do cinema, uma criação de hollywood. Mas e daí?
Alguém pode, em sã consciência, conceber um submarino
sem aquele tradicional "ping"? Uma saída é construirmos
o nosso próprio jogo de submarino. Retornar ao velho estilo -
naviozinhos passando ao fundo e crau... torpedo! Como fazer?
Toda a estrutura funcional do jogo se
baseia num cenário giratório, afinal estamos comandando
a ação através do periscópio do submarino.
O cenário gira 360 graus e obter isso no Delphi
é a maior moleza. Partimos de uma imagem que defini com 1.440
pixels na horizontal por 186 pixels
na vertical. Como fiz a imagem? Calma, que isso será tratado
em outra parte.
A largura, embora não represente
nenhuma mirabolância matemática, equivale a quatro vezes
360, ou seja, cada "direção"
teria uma representação de 360
pixels. A razão? Achei que o tamanho ficava legal,
em relação à tela do micro. Nada científico,
mas os jogos são feitos assim mesmo: sem grandes mágicas
compucabalísticas.
Obviamente que estou pensando em um "visor"
com essas mesmas medidas: 360 x 186.
Assim, num formulário vazio eu crio duas TImage:
uma com essas medidas (que chamarei de Tela) e outra com 1440
x 186, que chamarei de Image1 e que deverá
ficar com seu atributo Visible em false e deverá
conter a imagem do mar.
O controle de movimento do periscópio
é feito ao pressionar o botão esquerdo do mouse e movimentando-o
para a direita e esquerda. Como a imagem do mar é maior que o
visor, teremos, a cada "clicada" e movimento, que determinar a porção
do mar que deve ficar à vista. Para isso usaremos uma variável
global, chamada Pos (uma integer).
Se Pos = 0 então o pedaço
(360 pixels) mais à esquerda do mar é mostrado; se Pos
= 1439, então o pedaço (360 pixels) mais à
direita é mostrado, certo?
Errado. Há um problema aqui, pois
se Pos for maior que 1079 (360 x 3 = 1080)
então a imagem será formada pelo pedaço que sobrou
do mar e mais um pedaço do início da imagem. Claro, se
estamos considerando um periscópio que gira livremente os 360
graus. Veja o esboço abaixo:
O truque da programação
se resume em verificar se Pos está dentro desta área crítica
(acima de 1080) e então proceder
à transferência do "pedaço" de cenário para
a área do visor. Primeiro criamos um grupo de variáveis
globais, para uso deste esquema: Pos e Px, ambas integer (Px
é apenas uma variável de controle); Pk como byte
(para controle do botão do mouse) e PosMou como TPoint
(para guardar as coordenadas originais do mouse, quando o botão
é pressionado).
No evento OnMouseDown,
da TImage Tela fazemos:
Pk:= 1; Px:= X; Screen.Cursor:= crNone;
PosMou:= Mouse.CursorPos;
if Pk = 1 then begin
Pos:= Pos + ((X - Px)*3); Px:= X;
if Pos < 0 then Pos:= 1440;
if Pos > 1440 then Pos:= 0;
MontaTela; Tela.Repaint;
end;
Pk:= 0; Screen.Cursor:= crDefault;
Mouse.CursorPos:= PosMou;
A montagem da visão
foi colocada numa procedure independente para que possamos ir incrementando-a
aos poucos. Ei-la:
procedure MontaTela;
var
T1,T2: HBitmap;
begin
T1:= Form1.Tela.Canvas.Handle;
T2:= Form1.Image1.Canvas.Handle;
if Pos < 1080 then
BitBlt(T1,0,0,360,186,T2,Pos,0,srccopy)
else begin
BitBlt(T1,0,0,1440-Pos,186,T2,Pos,0,srccopy);
BitBlt(T1,1440-Pos,0,Pos-1080,186,T2,0,0,srccopy);
end;
end;
Note que a primeira coisa a ser feita
é a verificação de Pos. Se ela está dentro
da faixa determinada, a impressão da visão é feita
numa única operação. Caso contrário, é
feita a impressão da primeira parte e depois da segunda parte.
Rode o programa e veja como o periscópio funciona perfeitamente.
Tudo o que for colocado dentro do cenário, como os navios, trilha
dos torpedos, etc, será montado junto com a visão do jogador.
Aí você pergunta: mas é
só isso? Sim, basicamente é só isso. O resto é
adereço, que a gente inventa para melhorar o jogo e para criar
desafios ao jogador. Olhando para a procedure MontaTela
conclui-se que a maior parte do trabalho, na criação deste
tipo de jogo, fica mesmo por conta dos "gráficos". De fato, este
é o grande truque da criação desses joguinhos modernosos:
conhecer e praticar a manipulação/edição
de imagens. Uma prática que passa a milhas náuticas de
distância de profundos conhecimentos de programação,
linguagem C e demais cacarecos.
|
|
|