projetos e jogos abertos
 
 
Preparar, apontar, fogo...
Como mudar o desenho do cursor e o sistema de mira
 

 

Já sabemos como disparar os mísseis e como eles se direcionam. O que está faltando agora é um sistema de miras, ou seja, um sistema para selecionar o alvo desejado. Como fazer? Mole, mole.

Partiremos de um cursor do mouse todo especial. A figura ao lado irá orientá-lo para que você edite esse nosso novo cursor. Mas não iremos implementar mais este recurso ao nosso sistema. Iremos sim, alterar um dos cursores default que não usamos, o crMultiDrag por exemplo.

Estando no Delphi, ative o editor de imagens no menu Tools. Abra o subdiretório Lib, do próprio Delphi e acesse o arquivo controls.res. Abra o recurso 32763 que é justamente o dito cujo do cursor crMultiDrag.

Basta editá-lo conforme a figura aí ao lado ou, para os preguiçosos, basta carregar o arquivo Mira.cur, selecioná-lo, copiá-lo para o clipboard e depois "pasteá-lo" para o tal recurso 32763.

Lembre-se que o Hot Spot da mira deverá ser 5,5. Não sabe o que é Hot Spot? Xiiiii! Hot Spot é o ponto, dentro da área do cursor, que corresponderá às coordenadas x,y ao clicarmos os botões ou deslocarmos o cursor pela tela. Em nosso caso, interessa que esse ponto seja o canto superior esquerdo da área interna da mira e não a mira toda. Assim iremos mapear somente o que estiver dentro dela, para efeito de seleção de alvo.

Preste atenção na figura ao lado. Note que a área central é formada por uma matriz de 6 x 6 pixels, a partir do Hot Spot do cursor. Essa será a nossa área de varredura para localizarmos o nosso alvo.

Para proceder à localização, basta consultar a matriz dos mísseis. Se houver alguma coordenada X,Y dentro da área ativa do alvo, bingo.

Mis[Qms,0]:= X   Coordenadas X,Y do ponto
Mis[Qms,1]:= Y
Mis[Qms,2]:= X2  Coordenadas X2,Y2 do alvo
Mis[Qms,3]:= Y2
Mis[Qms,4]:= C   Contador
Mis[Qms,5]:= L   Largura
Mis[Qms,6]:= S   Altura
Mis[Qms,7]:= Mx  Flags (+1) ou (-1)
Mis[Qms,8]:= My

O movimento dos Patriots é o mais complexo, pois a cada mudança de posição é preciso testar se o alvo não foi atingido. Vamos considerar, para evitar os "erros" de contas, que o Scud será abatido se o Patriot chegar a 2 pixels de distância dele.

Se não for assim, teremos que criar um timer especial para os Patriots, pois se eles ficarem na "rabeira" dos Scuds e voando na mesma velocidade, nunca alcançarão seus objetivos. Clique aqui e baixe o pacote zip com os fontes do jogo até esta etapa.

{---------- Início do programa / comentário --------------}

QUARTA PARTE

Primeiro definimos o evento OnMouseMove, na tela do Radar,
para que possamos mapear o deslocamento do cursor:

begin
   Mpx:= X; Mpy:= Y;
end;

No evento OnClick, ainda do Radar, montamos o controle de
disparo dos mísseis:

label
   Vago,Fim;
var
   Temp: integer;
begin
   Cms:= clAqua;
   for Qms:= 10 to 29 do if Mis[Qms,0] = 0 then goto Vago;
   goto Fim;
Vago:
   {Se tem mísseis na base, então...}
   if ParBase[(Base*2)-1] > 0 then begin
      {Coloca o tipo de míssil no controle do míssil /Qms}
      Tip[Qms,0]:= ParBase[(Base-1)*2];
      {Menos um míssil na base}
      ParBase[(Base*2)-1]:= ParBase[(Base*2)-1]-1;
      {Desativa a base se foi o último míssil}
      if ParBase[(Base*2)-1] = 0 then ParBase[(Base-1)*2]:= 0;
      {Mostra os dados da base}
      MostraDin; AtivarBase(Base);
      Tip[Qms,1]:= 0; Tip[Qms,2]:= 0;
      {Se for míssil patriot, então identifica o alvo}
      if Tip[Qms,0] = 1 then begin
         Tip[Qms,1]:= 90; for Temp:= 0 to 9 do
             if (Mis[Temp,0] > Mpx) and (Mis[Temp,0] < Mpx+5) and
                (Mis[Temp,1] > Mpy) and (Mis[Temp,1] < Mpy+5) then
                 Tip[Qms,2]:= Temp+1;
         end;
      {Coordenadas de lançamento do míssil}
      X1:= BasCord[(Base-1)*2]; Y1:= BasCord[(Base*2)-1];
      {Coordenadas do alvo / cursor do mouse}
      X2:= Mpx; Y2:= Mpy; PreparaMissil; end;
Fim:
end;

Agora precisamos reescrever o evento OnTimer, que controla
o deslocamento dos mísseis (AwacsTimer).

var
   TelRad: HBitmap;
begin
   TelRad:= Radar.Canvas.Handle;
   if Base <> 0 then begin
      {Se as bases estiverem operante...}
      if AvRad1 <> 1000 then begin
         {Se o avião 1 estiver voando...}
         SetPixel(TelRad,AvRad1,40,SkRad1);
         {Recupera o que estava antes na coordenada}
         dec(AvRad1);
         {Move o avião para a esquerda um pixel}
         if AvRad1 = 0 then begin
            {Se já deu uma volta completa...}
            Aviao1.Progress:= Aviao1.Progress-1;
            {Diminui a barra}
            if Aviao1.Progress = 0 then AvRad1:= 1000 else
               AvRad1:= 453;
            {Se cumpriu a missão, pousa o avião, ou então
             recoloca-o no canto direito}
            end;
         SkRad1:= GetPixel(TelRad,AvRad1,40);
         {Salva o conteúdo original da posição}
         SetPixel(TelRad,AvRad1,40,clYellow);
         {Plota o avião}
         end;

      if AvRad2 <> 1000 then begin
         SetPixel(TelRad,AvRad2,120,SkRad2);
         dec(AvRad2); if AvRad2 = 0 then begin
            Aviao2.Progress:= Aviao2.Progress-1;
            if Aviao2.Progress = 0 then AvRad2:= 1000 else
            AvRad2:= 453;
            end;
         SkRad2:= GetPixel(TelRad,AvRad2,120);
         SetPixel(TelRad,AvRad2,120,clYellow);
         end;

      if AvRad3 <> 1000 then begin
         SetPixel(TelRad,AvRad3,202,SkRad3);
         dec(AvRad3); if AvRad3 = 0 then begin
            Aviao3.Progress:= Aviao3.Progress-1;
            if Aviao3.Progress = 0 then AvRad3:= 1000 else
               AvRad3:= 453;
            end;
         SkRad3:= GetPixel(TelRad,AvRad3,202);
         SetPixel(TelRad,AvRad3,202,clYellow);
         end;

      if AvRad4 <> 1000 then begin
         SetPixel(TelRad,AvRad4,282,SkRad4);
         dec(AvRad4); if AvRad4 = 0 then begin
            Aviao4.Progress:= Aviao4.Progress-1;
            if Aviao4.Progress = 0 then AvRad4:= 1000 else
               AvRad4:= 453;
            end;
         SkRad4:= GetPixel(TelRad,AvRad4,282);
         SetPixel(TelRad,AvRad4,282,clYellow);
         end;

      {Testa se tem Scud voando}
      Cms:= clRed; for Qms:= 0 to 9 do
         if Mis[Qms,0] <> 0 then MoveMissil;

      {Testa os nossos mísseis}
      Cms:= clAqua; for Qms:= 10 to 29 do begin
         {Se for Patriot sem rumo, movimenta-o}
         if Tip[Qms,2] = 255 then begin
            SetPixel(TelRad,Mis[Qms,0],Mis[Qms,1],Mcr[Qms]);
            Mis[Qms,0]:= 0; Tip[Qms,2]:= 0; end;
         {Se for Patriot com alvo definido...}
         if Tip[Qms,2] <> 0 then Teleguiado;
         if (Mis[Qms,0] <> 0) and (Tip[Qms,2] <> 255)
            then MoveMissil;
         end;

      Radar.Repaint;
   end;
end;

Para controlar os patritos que estão com um alvo definido,
faremos uma procedure à parte:

procedure Teleguiado;
label
   Fim;
var
   TelRad: HBitmap;
begin
   {Realinha o alvo}
   Mis[Qms,2]:= Mis[Tip[Qms,2]-1,0];
   Mis[Qms,3]:= Mis[Tip[Qms,2]-1,1];
   {Verifica se atingiu o scud}
   if (Mis[Qms,0] >= Mis[Qms,2]-2) and
      (Mis[Qms,0] <= Mis[Qms,2]+2) and
      (Mis[Qms,1] >= Mis[Qms,3]-2) and
      (Mis[Qms,0] <= Mis[Qms,2]+2) then begin
         {Acertou.... VIVA!!!!!}
         TelRad:= Form1.Radar.Canvas.Handle;
         Mcr[Qms]:= Mcr[Tip[Qms,2]-1];
         SetPixel(TelRad,Mis[Qms,2],Mis[Qms,3],clWhite);
         SetPixel(TelRad,Mis[Qms,0],Mis[Qms,1],Mcr[Qms]);
         Mis[Qms,0]:= Mis[Qms,2]; Mis[Qms,1]:= Mis[Qms,3];
         Mis[Tip[Qms,2]-1,0]:= 0; Tip[Qms,2]:= 255;
      goto Fim; end;
   {Buuu! Perdeu o alvo}
   Mis[Qms,7]:= 1; Mis[Qms,8]:= 1;
   Mis[Qms,5]:= Mis[Qms,2]-Mis[Qms,0];
   if Mis[Qms,5] < 0 then begin
      Mis[Qms,5]:=Mis[Qms,0]-Mis[Qms,2]; Mis[Qms,7]:=-1; end;
   Mis[Qms,6]:= Mis[Qms,3]-Mis[Qms,1];
   if Mis[Qms,6] < 0 then begin
     Mis[Qms,6]:=Mis[Qms,1]-Mis[Qms,3]; Mis[Qms,8]:=-1; end;
   if Mis[Qms,5]>=Mis[Qms,6] then Mis[Qms,4]:=Mis[Qms,6] div 2
      else Mis[Qms,4]:= Mis[Qms,5] div 2;
Fim:
end;

Agora é testar e "apreciar" os patriots abatendo os scuds.
Note como ele muda a trajetória de forma inteligente, para
melhor enquadrar o seu alvo.

{------------ Fim do programa / comentário ---------------}

  online