Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar...

23
Desenvolver Jogos em DelphiX

Transcript of Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar...

Page 1: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

Desenvolver Jogos em DelphiX

Page 2: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

Passos

• Adicionar o TDXDraw– Onde se passa toda a acção

• Adicionar um TDXImageList– Um por cada tipo de imagens(heroi, balas...)– Adicionar as imagens aos Items– Associar ao TDXDraw– NOTA: ao adicionar uma imagem esta deve de ficar em TDIB

• Adicionar um TDXWaveList– Para termos sons prontos a utilizar

• Adicionar um TDXTimer:– Colocar a propriedade enabled a false– Definir o intervalo de disparo– É aqui que está o focus da questão!!

Page 3: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

Classe’s VS Actores

• Construir Classes/UNIT’s para cada um dos actores do Jogo :type

TBullet = class(TImageSprite)

private

{colocar aqui atributos do actor}

public

{overload dos métodos que desejarmos redefinir} procedure DoMove(moveCount:integer);override;

procedure DoDraw();override;

procedure DoCollision(Sprite:TSprite;varDone:Boolean);override;

end;

{ utilizar class completion: ctrl^c }

Page 4: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

DXSprite Unit• Components

– TDXSpriteEngine• Objects

– TBackgroundSprite• Chips property can be specified• collision judgment can be set with the CollisionMapproperty

– TImageSprite• Onde a imagem é mostrada• Atributos:

– Image – imagem a mostrar• surface é Image.PatternSurfaces[AnimStart+AnimPos]

– TSprite• Class abstracta que apresenta os métodos:

– DoDraw– DoMove– DoColision

– TSpriteEngine• Controlo os sprites a ele associados

Page 5: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

Implementar os métodos de DXDraw para gestão dos eventos

• DXDrawInitialize{colocar o timer com 60 segs}dxtimer1.Interval := 1000 div 40;dxtimer1.enabled := true;{outras coisas que desejar iniciar}

• DXDrawFinalizedxtimer1.enabled := true;

Nota: as afectações ao Timer devem de ser feitas sempre nestes métodos por definição.

Page 6: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

TDXTimer – o responsável (1)• Este objecto é quem contém o código importante da aplicação, pois permite

o evoluir do jogo:{se não conseguirmos desenhar, terminamos}

if (dxdraw1.canDraw = false) then exit; {actualiza a situação de input nos estados} DXInput1.Update();

{desenhar o fundo: sem stretch} DXImageFundos.Items[0].Draw( dxdraw1.surface, 0, 0, 0);

{colocar a superficie com cor} DXDraw1.Surface.Fill( dxdraw1.surface.colormatch(

RGB(0,100, 200)) ); {actualizar o ecrã, limpando os objectos mortos} DXSpriteEngine1.Dead(); {chamada aos DoMove dos actores com um numero de pixels} DXSpriteEngine1.move(2); {desenhar os sprites na superficie de fundo} DXSpriteEngine1.Draw();

Page 7: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

TDXTimer – o responsável (2)

• O seguinte código também pode ser adicionado:{utilizado para mostrar os frames per segundo e valores de

variaveis} with DXDraw1.Surface.canvas do begin Brush.Style := bsClear; Font.Color := clRed; Font.Size := 20; TextOut(0, 0, 'fps: ' +

intToStr(DXTimer1.FrameRate)); Release(); {obrigatorio} end;

• Nunca esquecer NO FIM: {nao aparece nada sem esta chamada} DXDraw1.flip();

Page 8: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

Criação dos objectos

• A criação é feita no Form onCreate event handler: {criar o jogo}

theGame := TGame.Create(); theGame.sprite := dxSpriteEngine1.engine; theGame.spriteEngine := dxdraw1; theGame.input := dxInput1; theGame.sound := dxSound1; theGame.imageListFUndos := dxImageFundos; theGame.imageListWalls := DXImageListWall; theGame.imageListHeroi := DXImageListHeroi; theGame.waveListHeroi := DXWaveHeroi; theGame.pontos := 0; {criar os actores} // criar o Heroi theHeroi := THeroi.Create(theGame);

• theGame e theHeroi é um atributo da form1• Na criaçao do jogo faz-se sempre a associação entre os componentes

DelphiX da form e a instância de TGame

Page 9: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

TImageSprite – atributos

• TImageSprite– AnimCount– AnimLooped– AnimPos– AnimSpeed– AnimStart– Image– PixelCheck– Tile

•Derived from TSprite–BoundsRect–ClientRect–Collisioned–Count–Engine–Height–Items–Moved–Parent–Visible–Width–WorldX–WorldY–X–Y–Z

Page 10: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

Um Actor

• Um Actor encontra-se associado a um jogo, logo para se construir um novo Actor deriva-se da classe TActor:

type TActor = class (TImageSprite) protected game: TGame; public

{apresenta um contructor apenas} constructor Create(game: TGame); end;

implementation

constructor TActor.Create(game: TGame);begin inherited Create(game.sprite); {associa o sprite} self.game := game; {associa-se ao jogo}

self.z := 10; {atribui um valor por omissão ao Z}end;

Page 11: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

Dica

• Não esquecer de fazer a destruição de todos os actores e game no form onDestroy event handler:

theGame.free();

theGun.free();

Page 12: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

TGame

• O Tipo TGame representa o Jogo• Existe para simplificar e aproveitar as capacidades

drag-drop do Delphi• Difere de jogo para jogo• Apresenta como atributos :

– tudo o que representa o jogo • (e.g.) score, vidas, tempo

– os elementos DelphiX utilizados• (e.g.) TDXWaveList’s, TDXImageList’s, TDXInput...

• Os atributos não são privados o que viola as regras de OOP, no entanto foi o melhor possível...

• Os atributos são afectados no evento de Create da form que contém os componentes.

Page 13: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

(e.g) TGametype TGame = class // o que é indispensável {sempre} sprite : TSprite; spriteEngine: TDXDraw; input: TDXInput; sound: TDXSound; // imageLists necessarias imageListFUndos: TDXImageList; imageListWalls: TDXImageList; imageListHeroi: TDXImageList; // wavelists necessarias waveListHeroi: TDXWaveList; // atributos necessarios ao Jogo pontos: integer; vidas: integer; end;

Page 14: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

Definição de um novo Actor

Derivar da classe TActor que deriva de TImageSprite: THeroi = class(TActor) private left, right, up, down: boolean;

public constructor Create(game:TGame);

procedure DoDraw();override; procedure DoMove(moveCount:integer);override; procedure DoCollision(sprite: TSprite; var Done:boolean);override; end;

• Redefinir os métodos em que estamos interessados.(exemplos de seguida)

• Nota: os atributos que se encontram apresentados são específicos deste Tipo

• Nota: cada Actor deve de existir numa única UNIT: encapsulamento.

Page 15: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

O Constructor• A cada Actor está associado sempre um Game que é afectado

no Constructor – método Create(..):constructor THeroi.Create(game: TGame);begin inherited Create(game); {obrigatório} self.Image := self.game.imageListHeroi.Items[0]; self.Width := self.Image.Width; self.height := self.Image.Height; self.x := self.game.spriteEngine.Width div 2; self.y := self.game.spriteEngine.height -

(2*self.Image.Height); left := false;

right := false; up := false; down := false;end;

• É no constructor que se afectam os atributos que representam o Actor

Page 16: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

Os Intervenientes

Page 17: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

Movimento dos Objectos

• A redefinição do método onMove que é responsável pelo movimento:procedure THeroi.DoMove (moveCount: integer);begin inherited DoMove(moveCount);

if(isLeft in self.game.input.States) thenself.X := self.X - moveCount;

if(isRight in self.game.input.States) thenself.X := self.X + moveCount;

if(isUp in self.game.input.States)thenself.y := self.y - moveCount;

if(isDown in self.game.input.States) thenself.y := self.y + moveCount;

collision(); {para testar se houve colisões}end;

Pode ser utilizado para mexer todos os actores de igual forma.

É afectado no evento de DXTimer construção do TGame

Page 18: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

BMP’s especiais – animação do Heroi

// animar o heroi

self.AnimPos := 0;

self.AnimStart := 20;

self.AnimCount := 6;

self.AnimSpeed := 5/1000;

self.AnimLooped := true;

Nota: as propriedades ParentHeight e ParentWidth têm que ser alterardas para representar o tamanho do Heroi

Page 19: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

Choque – detecção de colisões?

• Sempre que é feito um movimento verifica-se se houve choque com outro actor de um tipo especificado:

procedure THeroi.DoCollision(sprite: TSprite; var Done: boolean);

begin

inherited;

if (sprite is TWall) then

begin

self.game.waveListHeroi.items[0].play(false); {gritar!!??}

end;

end;

Page 20: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

Acesso a imagens ou sons

• Todos os TActor estão associados um game que conhece:type

TGame = class

// o que é indispensável {sempre}// imageLists necessarias

imageListFUndos: TDXImageList;

imageListWalls: TDXImageList;

imageListHeroi: TDXImageList;

// wavelists necessarias

waveListHeroi: TDXWaveList;

// atributos necessarios ao Jogo

pontos: integer;

vidas : integer:

• Logo o acesso é feito da seguinte forma:self.game.waveListHeroi.items[0].play(false);

self.game.imageListHeroi.Items[0]; {[‘nomeImagem’]}

False: nao espera terminar o som

True: bloqueia

Page 21: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

Exemplo de um movimento pseudo-aleatorio

// a utilizar no DoMove if(random(30)=1) then begin self.Image := game.DXImageLaden.items[random(2)]; self.x := random(game.dxdraw1.Width); self.y := random(game.dxdraw1.height-self.Image.Height); end;

Não esquecer da chamada á função randomize(); no evento de criação da Form que contém o jogo.

Page 22: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

Carregar paredes (leitura da informação de um Ficheiro)

assignFile(fich, 'level1.txt'); reset(fich); cnt:=0; while (not eof(fich)) do begin read(fich, ch); if(not ((ch = #13) or (ch=#10)))then begin aux[cnt] := ch; cnt := cnt + 1; end; end; cnt:=0; for yy:=0 to 6 do for xx:=0 to 9 do begin if(aux[cnt]='0') then TWall.Create(theGame, xx, yy); cnt := cnt + 1; end;

var xx, yy: integer; fich: file of char; aux : array[0..100] of char; cnt: integer; ch: char;

Page 23: Desenvolver Jogos em DelphiX. Passos Adicionar o TDXDraw –Onde se passa toda a acção Adicionar um TDXImageList –Um por cada tipo de imagens(heroi, balas...)

Opções de Projecto – em Delphi

Project --> Options --> application

Pode-se alterar várias definições:– icon– title– Help file