Passo-a-passo

A construção do jogo super explicada

A estrutura passo-a-passo visa facilitar a compreensão do leitor acerca dos procedimentos de montagem de um programa. Basta seguir as instruções que são dadas e ver o resultado.

Existem duas formas de executar o passo-a-passo: na primeira (método antigo) o leitor imprime esta página e reproduz no Delphi as instruções, digitando as linhas de programação. É um método antigo, usado no tempo das revistas impressas e que tem como ponto alto o fato de ser a forma mais rápida do leitor se acostumar com comandos e digitações, na programação. Mas é um método demorado e pouco usado.

Aproveitando as facilidades do copy/paste, o segundo método foi totalmente criado e desenvolvido para as matérias da TILT. Os passos são os seguintes: selecione a área de listagem a seguir, faça um copy para o clipboard (ctrl + C) e no Delphi, na seção de programação, posicione o cursor depois da instrução final "end." e dê um paste 
(ctrl + v).

Depois basta ir seguindo as instruções e transferindo as linhas de programação para os seus devidos locais, dentro do programa.

{=========================================================}
{Início da listagem

1) Ajuste as propriedades do Form1 p/ os seguintes valores:

Caption: TanKiller
ClientHeight: 348
ClientWidth: 536
Height: 375
Width: 544

As demais propriedades ficam como estão. Esta regra serve
para os demais componentes.

2) Crie um TPanel (Standard) com as seguintes propriedades:

BevelOuter: bvLowered
Caption: ''
Color: clBlack
Height: 256
Left: 5
Top: 5
Width: 526

3) Crie uma TImage (Additional), dentro do Panel1, com as
   seguintes propriedades:

Align: alClient
Cursor: crCross
Picture: (carregue a imagem Tank01.bmp)

Esta TImage será nossa tela, onde iremos montar as demais
figuras e elementos gráficos do jogo. O acesso à tela será
feito pela API BitBlt, usando um handle apropriado.

4) Crie uma TImage (Additional), fora do Panel1, com as
   seguintes propriedades:

Height: 64
Left: 145
Name: Image2
Top: 275
Visible: False
Width: 128

5) Crie uma TImage (Additional), fora do Panel1, com as
   seguintes propriedades:

AutoSize: True
Height: 100
Left: 400
Name: Image3
Picture: (carregue a imagem Tank02.bmp)
Top: 245
Visible: False
Width: 131

Esta TImage contém o padrão que será usado para montar o
chão da tela. Serão quatro repetições e ele será montado
pela procedure que limpará a tela.

6) Crie uma TImage (Additional), fora do Panel1, com as
   seguintes propriedades:

AutoSize: True
Height: 32
Left: 10
Name: Image6
Picture: (carregue a imagem Tank03.bmp)
Top: 305
Visible: False
Width: 128

Esta é a matriz do tanque 0 Km. Agora podemos fazer o
tanque andar de um lado para outro da tela.

7) Crie um TTimer (System):

Interval: 60
Name: Timer1

8) Crie um TSpeedButton:

Caption: Iniciar
Height: 25
Left: 15
Top: 270
Width: 76

9) Crie as seguintes variáveis globais:

implementation
{$R *.DFM}
{
const
  Stat: byte = 0;  //Liga/desliga animação
  Tiro: byte = 0;  //Tiro em andamento

var
  Buf: TBitmap; // Buffer de tela
  Tx,Ty,Cx,Vt: integer;
  Tanques,Destrd,Ammo,Explod: integer;

10) Crie o evento OnClick, no SpeedButten1. Este botão irá
inicializar uma partida. A seguir digite as seguintes
linhas de programação, dentro da procedure:

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  Stat:= 2;
  Tanques:= 0; Destrd:= 0; Ammo:= 15;
end;

11) Antes de movimentar o tanque, vamos criar a procedure
que limpa a tela e a inicialização do programa:

procedure LimpaBuf;
var
  Chao,HBuf: HBitmap;
begin
  HBuf:= Buf.Canvas.Handle;
  Chao:= Form1.Image3.Canvas.Handle;
  Buf.Canvas.Brush.Color:= clBlack;
  Buf.Canvas.Pen.Color:= clBlack;
  Buf.Canvas.Rectangle(0,0,524,154);
  BitBlt(HBuf,0,154,131,100,Chao,0,0,SRCCOPY);
  BitBlt(HBuf,131,154,131,100,Chao,0,0,SRCCOPY);
  BitBlt(HBuf,262,154,131,100,Chao,0,0,SRCCOPY);
  BitBlt(HBuf,393,154,131,100,Chao,0,0,SRCCOPY);
end;

12) Crie o evento OnActivate, no Form1 (ajusta os parâm.ts
    inciais de funcionamento e cria o buffer de tela):

procedure TForm1.FormActivate(Sender: TObject);
begin
  Buf:= TBitmap.Create;       //Cria o buffer de tela
  Buf.Width:= Image1.Width;   //Largura
  Buf.Height:= Image1.Height; //Altura
  Buf.Canvas.Font.Color:= clLime;   //Parâmetros para a
  Buf.Canvas.Font.Name:= 'arial';   //impressão dos números
  Buf.Canvas.Font.Style:= [fsBold];
  Buf.Canvas.Font.Height:= 32;
end;

13) Crie o evento OnTimer, no Timer1 e coloque a seguinte
programação nele:

procedure TForm1.Timer1Timer(Sender: TObject);
var
  Fogo,HBuf,Tela,Tank,Matrz,Cano,Boom: HBitmap;
  ACan,Tmb,Mosca: integer;
  Num: string;
begin
  //Define os handles das imagens
  HBuf:= Buf.Canvas.Handle;
  Tela:= Image1.Canvas.Handle;
  Tank:= Image2.Canvas.Handle;
  //Pt 01:
  //Se tiver um tanque andando...
  if Stat = 1 then begin
    //Apaga todo o buffer de tela
    LimpaBuf;
    //Transfere o tanque para o buffer
    BitBlt(HBuf,Tx,Ty,128,64,Tank,0,0,SRCCOPY);
    //Pt02
    //Anda com o tanque dois pixels
    inc(Tx,2);
    //Se o tanque saiu da tela, recomeça com outro tanque
    if Tx > 530 then Stat:= 2;
    //Pt5
    //Transfere o buffer para a tela
    BitBlt(Tela,0,0,524,254,HBuf,0,0,SRCCOPY);
    Image1.Repaint;
  end;
  //Vai ser lançado um tanque novo
  if Stat = 2 then begin
    //Apaga o buffer do tanque
    Image2.Canvas.Brush.Color:= clBlack;
    Image2.Canvas.Pen.Color:= clBlack;
    Image2.Canvas.Rectangle(0,0,128,64);
    //Transfere a imagem de um tanque intacto para o buffer
    Matrz:= Image6.Canvas.Handle;
    BitBlt(Tank,0,32,128,32,Matrz,0,0,SRCCOPY);
    //Ajusta demais parâmetros
    Tx:= -128; Ty:= 90; Explod:= 0;
    inc(Tanques); Stat:= 1;
  end;
end;

Até aqui, ao compilar, o tanque será montado no buffer de
tela e irá andar da esquerda para a direita. Agora vamos
montar a arma do jogador e seus controles.

14) Crie uma TImage com as seguintes propriedades (cano da
    arma):

AutoSize: True
Height: 32
Left: 310
Name: Image4
Picture: (carregue a imagem Tank04.bmp)
Top: 305
Visible: False
Width: 48

15) Crie uma TImage com as seguintes propriedades (fogo que
    sai do cano da arma):

AutoSize: True
Height: 13
Left: 315
Name: Image5
Picture: (carregue a imagem Tank05.bmp)
Top: 290
Visible: False
Width: 20

16) Crie um TScrollBar com as seguintes propriedades (será o
    sistema de deslocamento do cano da arma):

Height: 11
LargeChange: 10
Left: 185
Max: 500
Min: 0
Position: 245
SmallChange: 10
Top: 270
Width: 156

17) Complemente o evento OnTimer com os seguintes códigos
    (nos seus respectivos locais assinalados - Pt ??):

  //Pt 01:
  Cano:= Image4.Canvas.Handle;
  Fogo:= Image5.Canvas.Handle;
  ...
    ...
    //Pt 02:
    //Verifica se a arma recuou (foi dado um tiro)
    if Tiro = 220 then Acan:= 230 else Acan:= 222;
    //Transfere a figura do cano da arma (c/máscara)
    BitBlt(HBuf,ScrollBar1.Position,Acan,24,32,
                                    Cano,24,0,SRCAND);
    BitBlt(HBuf,ScrollBar1.Position,Acan,24,32,
                                    Cano,0,0,SRCPAINT);
    //Pt03

Compile o que foi digitado até aqui e verifique se o cano da
arma está se deslocando pela tela como é esperado.

18) Agora vamos montar o botão que dispara os tiros. Crie
    um TSpeedButton com as seguintes propriedades:

Caption: DISPARAR
Height: 36
Left: 230
Top: 290
Width: 71

19) Crie o evento OnClick para este botão, com os seguintes
    códigos de programação:

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
  //Se não tem um tiro em andamento...
  if Tiro = 0 then begin
    //Se tem munição para atirar...
    if Ammo <> 0 then begin
      //Cx = distância do tiro à esquerda
      Cx:= ScrollBar1.Position+11;
      //Fator de deslocamento da bala
      Vt:= 32;
      //Menos um tiro
      dec(Ammo);
      //Lá vai bala...
      Tiro:= 220;
    end;
  end;
end;

20) Complemente o evento OnTimer com os seguintes códigos
    (nos seus respectivos locais assinalados - Pt ??):

    //Pt03:
    //Se tiver um tiro em andamento...
    if Tiro > 0 then begin
      //Define o comprimento da bala (1/2 pixels)
      if Tiro < 155 then Tmb:= 1 else Tmb:= 2;
      //Transfere a bala para o buffer
      BitBlt(HBuf,Cx,Tiro,1,Tmb,Cano,24,0,SRCCOPY);
      //Se o tiro foi dado agora, fogo na boca da arma
      if Tiro = 220 then begin
        //Transfere o fogo
        BitBlt(HBuf,Cx-4,216,10,13,Fogo,20,0,SRCAND);
        BitBlt(HBuf,Cx-4,216,10,13,Fogo,0,0,SRCPAINT);
      end;
      //Ajusta o próximo deslocamento do tiro
      dec(Tiro,Vt); Vt:= ((Vt + 2) div 2) + 1;
      //Se o tiro chegou no nível do alvo...
      if Tiro < 140 then begin
        //Calcula distância da margem esquerda do tanque
        Tiro:= 0; Mosca:= Cx-Tx;
        //Se acertou no tanque...
        if (Mosca < 120) and (Mosca > 10) then begin
          //Marca o tanque com o furo
          BitBlt(Tank,Mosca,51,2,2,Cano,20,0,SRCCOPY);
          //Se acertou na área da frente, grito do homem
          //if (Mosca > 95) and (Mosca < 99) then...
          //Se acertou no meio do tanque, grito do whookie
          //if (Mosca > 75) and (Mosca < 79) then...
          //Se acertou na trazeira (painel de munição)
          if (Mosca > 45) and (Mosca < 48) and (Explod = 0)
            then begin
            //Explode o tanque
            Explod:= 1; inc(Destrd); inc(Ammo,5);
          end;
        end;
      end;
    end;

ATENÇÃO: como a montagem do som envolve o uso do DGC e do
Direct-X, não vamos detalhá-lha aqui. Mas indicaremos onde
os efeitos sonoros ocorrem na versão original. Se quiser
mais detalhes sobre os sons, depois de montada a versão
passo-a-passo, recorra à versão completa do jogo.

Compile como está e veja os resultados. O tanque anda de
um lado para outro, o canhão se desloca de acordo com a
posição da ScrollBar e a bala, depois de disparada, segue
a trajetória em direção ao alvo.

21) A explosão do tanque, quando a bala acerta 1 determinado
    ponto, é feita no próprio evento OnTimer1. Basta
    complementar o Pt4:

    //Pt4
    //Se tem uma explosão em andamento...
    if (Explod > 0) and (Explod < 8) then begin
      Boom:= Image7.Canvas.Handle;
      //Transfere o frame da explosão para o tanque
      BitBlt(Tank,0,0,128,50,Boom,0,(Explod-1)*50,SRCCOPY);
      inc(Explod);
    end;

22) Crie uma TImage com as seguintes propriedades (explosão
    do tanque):

AutoSize: True
Height: 350
Left: 385
Name: Image7
Picture: (carregue a imagem Tank06.bmp)
Top: -5
Visible: False
Width: 128

23) Finalmente, informa ao jogador quantos tiros ainda lhe
    restam, quantos tanques passaram e quantos ele acertou.
    Basta acrescentar o trecho a seguir no Pt5, do evento
    OnTimer1:

    //Pt5
    //Imprime quantidade de tiros que ainda tem
    Buf.Canvas.Font.Color:= clLime;
    Num:= '00' + IntToStr(Ammo);
    Num:= copy(Num,length(Num)-2,3);
    Buf.Canvas.TextOut(5,0,Num);
    //Imprime quantos tanques já passaram
    Num:= '0' + IntToStr(Tanques);
    Num:= copy(Num,length(Num)-1,2);
    Buf.Canvas.TextOut(430,0,Num);
    //Imprime quantos tanques foram destruídos
    Buf.Canvas.Font.Color:= clRed;
    Num:= '0' + IntToStr(Destrd);
    Num:= copy(Num,length(Num)-1,2);
    Buf.Canvas.TextOut(480,0,Num);

Compile e divirta-se com o TanKiller.

Clique aqui e pegue o pacote zip com as imagens para o jogo.

 
online