|
|
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 ---------------}
|
|
|