AULA DE DELPHI parte 3 - CRIANDO UM PROTO-JOGO

Ver o tópico anterior Ver o tópico seguinte Ir em baixo

AULA DE DELPHI parte 3 - CRIANDO UM PROTO-JOGO

Mensagem por Da Galáxia em Qua 19 Jan 2011, 23:16

AULA DE DELPHI parte 3 - CRIANDO UM PROTO-JOGO

Aulas anteriores
aula 1 http://gmbr.forumeiros.com/t12273-aula-de-delphi-parte-i
aula 2 http://gmbr.forumeiros.com/t12408-aula-de-delphi-parte-2-calculadora-basica-em-delphi-ou-lazarus



PROTO-JOGO – estilo shooter lateral (esquerda para a direita) .


Primeiramente na raiz C:\ vamos criar uma pasta e chama-la de Proto_Jogo, copie e cole dentro desta pasta, 2 imagens: 1 para ser a nossa nave (vamos por o nome deste arquivo de nave mesmo) e outra para ser o nosso tiro(vamos por o nome deste arquivo de tiro mesmo), os arquivos de imagem nave e tiro devem ter a extenssão BMP. E tambem quando for salvar a unit e o projeto, salvar dentro desta nossa pasta. É que vai ser mais simplificado para nós, se as imagens estiverem juntas com a unit e o projeto na mesma pasta.


Agora entre no Delphi, va em FILE e SALVE ALL e ache a nossa pasta (Proto_Jogo) e salve dentro dela a unit e o projeto (escolham o nome que quiserem). Agora já temos dentro da nossa pasta o arquivo bmp nave, o arquivo bmp tiro e os arquivos da unit e do projeto.


OBS: A unit é a tela onde digitamos os códigos , lembrando que o DELPHI já cria automaticamente alguns códigos, para proporcionar ao programador uma melhor produtividade. Caso a unit estiver atrás do form e estiver ruin de puxa-la, basta apertar F12, e ainda se por algum motivo ela foi fechada é só ir em:
View, units e o nome da sua unit


Beleza, agora vamos programar:

Em VAR abaixo de Form1: TForm1; coloque:
Player: TNave;
Buffer: TBitmap;

Player é uma variável que criamos e TNave é o seu tipo(diferentemente
do TBitmap usado pela variável Buffer que é um tipo próprio, o tipo TNave é um tipo que vamos criar.
Buffer é uma variável que criamos e TBitmap é o seu tipo.
A variável Player vai ser nossa nave.
Mas por que criamos a variável que estamos chamando de Buffer?
Toda a vez que um objeto se movimenta na tela a imagem de sua posição anterior é apagada e redesenhada na posição atual, esse sistema “desenha, limpa e desenha” faz com que a imagem nós pareça piscando. Para resolver isto, ao invés de se desenhar direto na tela do computado armazena-se a imagem em um Bitmap, assim quando está começando a desenhar na tela, ao mesmo tempo esta armazenando no Bitmap, e a imagem flui com nitidez.

Criando o nosso tipo TNave.

Acima do type já feito pelo delphi crie outro type digitando isto:
type
TNave = record
X,Y: variant;
Sprite: TBitmap;
end;

Pronto, nosso tipo TNave foi criado, explicando-o:
X e Y vão ser usados para a posição e deslocamento de nossa nave
Sprite vai ser a imagem de nossa nave.


Criando nossa tela de jogo.
Click no form e a esquerda no menu object inspector, va na aba events, e em OnCreat dê duplo click na parte branca, pronto vc agora esta entre o begin e o end do procedure TForm1.FormCreate(Sender: TObject);

Coloque entre o begin e o end; isto:
Buffer:= TBitmap.create; //Cria a imagem do bitmap onde será desenhado nosso //proto-jogo
Buffer.Width:= 320; //Largura Máxima da imagem
Buffer.Height:= 240; //Altura Máxima da Imagem

OBS: Como ainda não fizemos o laço do programa, nada aparecera quando vc mandar executar. Então para maior assimilação, vamos criar agora o laço do programa, e a cada parte que fizermos vamos incrementa-lo, por enquanto apenas nossa tela de jogo.


Criando laço do proto-jogo
Click no form1 e a esquerda no menu object inspector, va na aba events, e em OnActivate dê duplo click na parte branca, pronto vc agora esta entre o begin e o end do procedure TForm1.FormActivate(Sender: TObject);
Coloque entre o begin e o end; isto:
while not Application.Terminated do //Enquanto a aplicação nao acaba
begin//inicio do laço
Form1.Canvas.Draw(0,0,Buffer);

Application.ProcessMessages;//Libera do laço principal
end;//fim do laço

Mande executar (seta verde no topo esquerdo do programa) e vc vai ver no canto superior esquerdo do form1 uma tela branca, é ai que nosso proto-jogo vai rodar. Vc pode mudar a posição desta tela, bastando alterar no laço o 0,0 antes do Buffer.


Agora vamos criar nossa nave.
Click no form e a esquerda no menu object inspector, va na aba events, e em OnCreat dê duplo click na parte branca, pronto vc agora esta entre o begin e o end do procedure TForm1.FormCreate(Sender: TObject); já estivemos aqui, lembra?

ABAIXO de Buffer.Height:= 240; coloque:

with player do//atributos do player
begin
X := 10; //Posição Inicial da nave
Y := 100; //Posição Inicial da nave
Sprite := TBitmap.Create; //Criar BMP
Sprite.LoadFromFile('nave.bmp'); //nosso arquivo bmp
Sprite.Transparent := True;//elimina a cor que esta fora da nave
end;

Se vc mandar executar, a nave NÃO vai aparecer, lembra por que? Ainda não informamos no nosso laço. Vamos fazer isto agora:

No laço (Abaixo de Form1.Canvas.Draw(0,0,Buffer); coloque:

Buffer.Canvas.Draw(Player.X,Player.Y,Player.Sprite);

Mande executar e lá esta nossa nave.

Agora apenas para economizar memória:
Click no form e a esquerda no menu object inspector, va na aba events, e em OnClose dê duplo click na parte branca, pronto vc agora esta entre o begin e o end do procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

Coloque entre o begin e o end; isto:
Action := caFree; //Libera o Formulário da Memória
Buffer.Destroy; //Libera o BackBuffer da Memória

Movimentando nossa nave.
Vc pode observar que até aqui todas as vezes que usamos um evento do formulário e foram 3 : OnCreat, OnActivate e OnClose, o DELPHI criou uma PROCEDURE, desta fez vamos ter que criar uma nós mesmos, mas não se preocupe, é fácil.

Lá em cima, debaixo das procedures e acima de Private coloque:
procedure LerTeclado(Sender: TObject); //aqui nos estamos declarando a procedure a //ser usada, da mesma forma que temos que declarar para as variáveis.

Podemos colocar esta nossa procedure em vários lugares do programa, mas para facilitar a localização vamos fazer como abaixo:

Acima do ultimo end. do programa, coloque:

procedure TForm1.LerTeclado(Sender: TObject);
begin

if (GetKeyState(VK_LEFT) < 0) and (Player.X > 1) then
Player.X := Player.X - 0.2;
if (GetKeyState(VK_RIGHT) < 0) and (Player.X < 287) then
Player.X := Player.X + 0.2;
if (GetKeyState(VK_UP) < 0) and (Player.Y > 10) then
Player.Y := Player.Y - 0.2;
if (GetKeyState(VK_DOWN) < 0) and (Player.y < 200) then
Player.Y := Player.Y + 0.2;
end;

OBS: Todas as segundas condições desses IFs são para que a nave respeite os limites da tela de jogo, para que não saia da tela. É claro que os valores vão depender do tamanho de sua sprite, modifique-os até que fique a seu gosto.

Agora para surtir efeito, no laço do programa abaixo de Buffer.Canvas.Draw(Player.X,Player.Y,Player.Sprite); COLOQUE:

LerTeclado(Form1);

Mande executar, e vc vai reparar que ao movimentar a nave borrões aparecerão na tela, isto acontece pois não mandamos apagar (limpar) as posições anteriores. Pois bem, vamos resolver isto. No laço, ABAIXO de Form1.Canvas.Draw(0,0,Buffer);coloque:

Buffer.Canvas.FillRect(BackBuffer.Canvas.ClipRect);


ATENÇÃO: É importante agora que o Buffer.Canvas.FillRect(BackBuffer.Canvas.ClipRect);
Fique abaixo do Form1.Canvas.Draw(0,0,Buffer); se não apaga tudo, e nada aparece.

Execute novamente e vera a nave se deslocando com fluidez e sem borrões.


Vamos atirar.

Vá em VAR e em baixo de Buffer: TBitmap; coloque 2 variaveis:

Bala : TNave; //vamos aproveitar o tipo que criamos para o player.
atira: boolean = true;

Agora é o seguinte:
Quem vai criar o tiro é nosso player quando apertarmos uma tecla (Z). Então na nossa PROCEDURE LER TECLADO em baixo de
Player.Y := Player.Y + 0.2; coloque:

if (getkeystate(ord('Z')) < 0) then //(ord('Z')) igual ao GM, pois este foi criado no Delphi
if(atira = true)then //atira
with bala do
begin
sprite:=Tbitmap.Create;
sprite.LoadFromFile('tiro.bmp');
sprite.Transparent:=true;
x:= player.x + 32 ; //modifique se necessario para que a bala saia do bico da nave
y:=player.y + 20 ; //modifique se necessario para que a bala saia do bico da nave
atira := false;//não atira mais
end;
if (bala.x > 320) then //320 - largura maxima da nossa tela de jogo.
atira := true;//volta a atirar

E no nosso laço, abaixo de LerTeclado(Form1); coloque:
Buffer.Canvas.Draw(Bala.X,Bala.Y,Bala.Sprite);

Agora vamos criar um TIMER para nossa bala se movimentar.
Na parte de cima do programa vá à aba SYSTEM, click em TIMER (um relógio) e click em qualquer ponto do form1.
Selecione o ícone timer e a esquerda em object inspector na aba properties em INTERVAL coloque 30. Dê duplo click no ícone timer e entre seu begin e end coloque:

bala.X:=bala.X + 20;//movimentação da bala

TERMINAMOS,.

ALGUMAS CONSIDERAÇÕES FINAIS
É claro que é apenas uma nave se movimentando em uma tela e atirando, mas dominando isto e com mais algum estudo vc vai conseguir construir um jogo em Delphi, e aprendendo isto vc leva alguma vantagem, pois em outras linguagens padrões como C++ o procedimento é parecido, ou seja vc vai ter que criar Tipos, vai ter que criar um Buffer, coisas que em GML são automáticas. O fundo que esta em branco, vc pode criar um cenário, basta criar uma imagem bmp do tamanho da tela e no laço coloca-lo antes de qualquer imagem (o que é desenhado primeiro fica atrás, ou é o contrário não me lembro), e se entendeu o tuto e ter atenção vc consegue. Outra coisa, em um atributo quando vc digita o ponto aparecem varios atributos para serem usados.


SEGUE ABAIXO COMO FICARIA A SUA UNIT

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
type
TNave = record
X,Y: variant;
Sprite: TBitmap;
end;
type
TForm1 = class(TForm)
Timer2: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure LerTeclado(Sender: TObject);
procedure Timer1Timer(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
Player: TNave;
Buffer: TBitmap;
Bala : TNave;
atira: boolean = true;
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
Buffer:= TBitmap.create; //Cria a imagem bitmap
Buffer.Width:= 320; //Largura Máxima da imagem
Buffer.Height:= 240; //Altura Máxima da Imagem

with player do//atributos do player
begin
X := 10; //Posição Inicial
Y := 100; //Posição Inicial


Sprite := TBitmap.Create; //Criar BMP!
Sprite.LoadFromFile('nave.bmp'); //puxa bmp
Sprite.Transparent := True;
end;



end;

procedure TForm1.FormActivate(Sender: TObject);
begin
while not Application.Terminated do //Enquanto a aplicação nao acaba
begin//inicio do laço
Form1.Canvas.Draw(0,0,Buffer);
Buffer.Canvas.FillRect(Buffer.Canvas.ClipRect);
Buffer.Canvas.Draw(Player.X,Player.Y,Player.Sprite);
LerTeclado(Form1);
Buffer.Canvas.Draw(Bala.X,Bala.Y,Bala.Sprite); // Desenha o tiro

Application.ProcessMessages;//Libera do laço principal
end;//fim do laço

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree; //Libera o Formulário da Memória
Buffer.Destroy; //Libera o BackBuffer da Memória

end;

procedure TForm1.LerTeclado(Sender: TObject); //eu criei
begin

if (GetKeyState(VK_LEFT) < 0) and (Player.X > 1) then
Player.X := Player.X - 0.2;
if (GetKeyState(VK_RIGHT) < 0) and (Player.X < 287) then
Player.X := Player.X + 0.2;
if (GetKeyState(VK_UP) < 0) and (Player.Y > 10) then
Player.Y := Player.Y - 0.2;
if (GetKeyState(VK_DOWN) < 0) and (Player.y < 200) then
Player.Y := Player.Y + 0.2;

if (getkeystate(ord('Z')) < 0) then
if(atira = true)then //atira
with bala do
begin
sprite:=Tbitmap.Create;
sprite.LoadFromFile('tiro.bmp');
sprite.Transparent:=true;
x:= player.x + 32 ;
y:=player.y + 20 ;
atira := false;//não atira mais
end;
if (bala.x > 320) then
atira := true;//volta a atirar

end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
bala.X:=bala.X + 10;//movimentação da bala
end;


end.

//Copiei e colei para testar e funcionou, espero que tenham gostado, qualquer duvidas é so postar.

Da Galáxia

Número de Mensagens : 348
Data de inscrição : 14/01/2010
Reputação : 1
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Ver o tópico anterior Ver o tópico seguinte Voltar ao Topo

- Tópicos similares

 
Permissão deste fórum:
Você não pode responder aos tópicos neste fórum