<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>UnderCode &#187; animação</title>
	<atom:link href="http://undercode.wordpress.com/tag/animacao/feed/" rel="self" type="application/rss+xml" />
	<link>http://undercode.wordpress.com</link>
	<description>Novo blog em http://www.mottaweb.com.br/</description>
	<lastBuildDate>Tue, 10 Nov 2009 15:32:01 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>pt-br</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='undercode.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/ad0de3a3817ed8afaf3e35be561c7d83?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>UnderCode &#187; animação</title>
		<link>http://undercode.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://undercode.wordpress.com/osd.xml" title="UnderCode" />
		<item>
		<title>Criando jogos em Delphi &#8211; Parte IV</title>
		<link>http://undercode.wordpress.com/2009/03/09/criando-jogos-em-delphi-parte-iv/</link>
		<comments>http://undercode.wordpress.com/2009/03/09/criando-jogos-em-delphi-parte-iv/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 14:37:03 +0000</pubDate>
		<dc:creator>KillDream</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[animação]]></category>
		<category><![CDATA[desenvolvimento de jogos]]></category>
		<category><![CDATA[windows GDI]]></category>

		<guid isPermaLink="false">http://undercode.wordpress.com/?p=68</guid>
		<description><![CDATA[- Animações -
&#160;&#160;&#160; Quando várias imagens são mostradas em um curto intervalo de tempo, nosso cérebro interpreta isso como movimento. À freqüência de imagens mostradas damos o nome de FPS (Frames per Second, em inglês). Filmes normalmente utilizam 30 quadros (frames) por segundo, enquanto os jogos mais atuais utilizam 60 quadros. Note que 15 é [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=undercode.wordpress.com&blog=3870490&post=68&subd=undercode&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><b>- Animações -</b></p>
<p>&nbsp;&nbsp;&nbsp; Quando várias imagens são mostradas em um curto intervalo de tempo, nosso cérebro interpreta isso como movimento. À freqüência de imagens mostradas damos o nome de <b>FPS</b> (<i>Frames per Second</i>, em inglês). Filmes normalmente utilizam 30 quadros (frames) por segundo, enquanto os jogos mais atuais utilizam 60 quadros. Note que 15 é o mínimo de quadros aceitável em uma animação, mas quanto mais quadros por segundo uma animação tiver, mais suave ela será.</p>
<p>&nbsp;&nbsp;&nbsp; Teoria básica apresentada, vamos ao que interessa. Para montarmos uma animação no Delphi, tudo o que precisaremos é mostrar uma seqüência de imagens na tela. Mas como mostrar essa seqüência? Simples. Vamos usar variáveis para recordar qual quadro devemos mostrar na tela, e por quanto tempo ele ainda deve ser mostrado na tela.</p>
<p><b>- A classe TAnimation-</b></p>
<p>&nbsp;&nbsp;&nbsp; Para controlar a animação vamos criar uma classe, nesse caso a <strong>TAnimation</strong>, que derivará apenas de TObject (como todas as classes em Delphi derivam de TObject, nós podemos deixar essa herança implícita). Essa classe precisa guardar uma matriz contendo as imagens de cada quadro, o quadro que está sendo mostrado atualmente e o tempo de espera entre um quadro e outro. Além disso, ela precisa de uma rotina que atualize a animação. Essa rotina recebe o tempo decorrido e atualiza a variável que guarda o tempo que o quadro atual foi exibido. Se esse tempo for maior do que o tempo de espera, alteramos o quadro da animação. Por fim, precisamos de uma rotina para desenhar o quadro atual na tela. Sabendo disso, podemos criar a nossa classe.</p>
<p><code><b><font color="#000080">type</b></font><br />
&nbsp;&nbsp;<font color="#008000"><i>//Aqui nós declaramos a classe da nossa explosão</font></i><br />
&nbsp;&nbsp;TAnimation = <b><font color="#000080">class</b></font><br />
&nbsp;&nbsp;<b><font color="#000080">private</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;fFrame: Integer; <font color="#008000"><i>//o quadro atual da animação</font></i><br />
&nbsp;&nbsp;&nbsp;&nbsp;fDelay: Integer; <font color="#008000"><i>//o tempo de espera entre um quadro e outro (em ms)</font></i><br />
&nbsp;&nbsp;&nbsp;&nbsp;fDelayed: Double; <font color="#008000"><i>//o tempo que o frame atual foi exibido na tela (em ms)</font></i><br />
&nbsp;&nbsp;&nbsp;&nbsp;fSpeed: Double; <font color="#008000"><i>//a velocidade da animação</font></i><br />
&nbsp;&nbsp;&nbsp;&nbsp;fX, fY: Double; <font color="#008000"><i>//a posição da animação no formulário</font></i><br />
&nbsp;&nbsp;&nbsp;&nbsp;fFrames: <b><font color="#000080">array</b></font> <b><font color="#000080">of</b></font> TBitmap; <font color="#008000"><i>//os frames da animação</font></i><br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">procedure</b></font> setFrame(value: Integer);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">procedure</b></font> setDelayed(value: Double);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">procedure</b></font> setFrameImage(Index: Integer; value: TBitmap);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">function</b></font> getFrame(Index: Integer): TBitmap;<br />
&nbsp;&nbsp;<b><font color="#000080">public</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">property</b></font> Frame: Integer read fFrame write setFrame;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">property</b></font> Delay: Integer read fDelay write fDelay;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">property</b></font> Delayed: Double read fDelayed write setDelayed;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">property</b></font> Speed: Double read fSpeed write fSpeed;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">property</b></font> X: Double read fX write fX;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">property</b></font> Y: Double read fY write fY;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">property</b></font> Image[Index: Integer]: TBitmap read getFrame write SetFrameImage;<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">constructor</b></font> Create;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">destructor</b></font> Destroy; override;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000"><i>//desenha o quadro atual na tela</font></i><br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">procedure</b></font> Paint(canvas: TCanvas);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000"><i>//atualiza a animação</font></i><br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">procedure</b></font> Update(lag: Integer);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000"><i>//seta os frames a partir de uma array de bitmaps</font></i><br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">procedure</b></font> SetFrames(values: <b><font color="#000080">array</b></font> <b><font color="#000080">of</b></font> TBitmap);<br />
&nbsp;&nbsp;<b><font color="#000080">end</b></font>;<br />
&nbsp;<br />
<b><font color="#000080">implementation</b></font><br />
&nbsp;<br />
<font color="#008000"><i>// --------------------------------------------------------------------------</font></i><br />
<font color="#008000"><i>// TAnimation</font></i><br />
<font color="#008000"><i>// -----------</font></i><br />
&nbsp;<br />
<font color="#008000"><i>// Inicializa a classe</font></i><br />
<b><font color="#000080">constructor</b></font> TAnimation.Create;<br />
<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;<b><font color="#000080">inherited</b></font> Create;<br />
&nbsp;&nbsp;fFrame:= <font color="#0000FF">0</font>;<br />
&nbsp;&nbsp;fDelay:= <font color="#0000FF">0</font>;<br />
&nbsp;&nbsp;fDelayed:= <font color="#0000FF">0</font>;<br />
&nbsp;&nbsp;fX:= <font color="#0000FF">0</font>;<br />
&nbsp;&nbsp;fY:= <font color="#0000FF">0</font>;<br />
&nbsp;&nbsp;fSpeed:= <font color="#0000FF">1</font>;<br />
&nbsp;&nbsp;setLength(fFrames, <font color="#0000FF">0</font>);<br />
<b><font color="#000080">end</b></font>;<br />
&nbsp;<br />
<font color="#008000"><i>// Destrói a instancia</font></i><br />
<b><font color="#000080">destructor</b></font> TAnimation.Destroy;<br />
<b><font color="#000080">var</b></font> i: Integer;<br />
<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;<b><font color="#000080">for</b></font> I := <font color="#0000FF">0 </font><b><font color="#000080">to</b></font> High(fFrames) <b><font color="#000080">do</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;FreeAndNil(fFrames[I]);<br />
&nbsp;&nbsp;setLength(fFrames, <font color="#0000FF">0</font>);<br />
&nbsp;&nbsp;FreeAndNil(fFrames);<br />
&nbsp;&nbsp;<b><font color="#000080">inherited</b></font> Destroy;<br />
<b><font color="#000080">end</b></font>;<br />
&nbsp;<br />
<font color="#008000"><i>// Retorna a imagem do frame atual</font></i><br />
<font color="#008000"><i>// Gera um erro se o índice (Index) estiver fora dos limites da matriz de</font></i><br />
<font color="#008000"><i>// frames.</font></i><br />
<b><font color="#000080">function</b></font> TAnimation.getFrame(Index: Integer): TBitmap;<br />
<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;<b><font color="#000080">if</b></font> (Index &lt; <font color="#0000FF">0</font>) <b><font color="#000080">or</b></font> (Index &gt; High(fFrames)) &nbsp;<b><font color="#000080">then</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">raise</b></font> Exception.Create(<font color="#0000FF">'Índice da animação fora da faixa permitida.'</font>);<br />
&nbsp;&nbsp;Result:= fFrames[Index];<br />
<b><font color="#000080">end</b></font>;<br />
&nbsp;<br />
<font color="#008000"><i>// Desenha o frame atual no canvas</font></i><br />
<b><font color="#000080">procedure</b></font> TAnimation.Paint(canvas: TCanvas);<br />
<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;<b><font color="#000080">if</b></font> fFrame &lt; <font color="#0000FF">0 </font><b><font color="#000080">then</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;exit;<br />
&nbsp;&nbsp;canvas.Draw(Round(fX), Round(fY), fFrames[fFrame]);<br />
<b><font color="#000080">end</b></font>;<br />
&nbsp;<br />
<font color="#008000"><i>// Modifica o tempo que o frame atual foi exibida</font></i><br />
<font color="#008000"><i>// Se este tempo for maior ou igual ao tempo que precisamos esperar, passa</font></i><br />
<font color="#008000"><i>// para o próximo frame.</font></i><br />
<b><font color="#000080">procedure</b></font> TAnimation.setDelayed(value: Double);<br />
<b><font color="#000080">var</b></font> incFrame: Integer;<br />
<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;fDelayed:= value;<br />
&nbsp;&nbsp;<b><font color="#000080">if</b></font> fDelayed &gt;= fDelay <b><font color="#000080">then</b></font><br />
&nbsp;&nbsp;<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;incFrame := floor(fDelayed / fDelay);<br />
&nbsp;&nbsp;&nbsp;&nbsp;fDelayed:= floor(fDelayed) <b><font color="#000080">mod</b></font> fDelay;<br />
&nbsp;&nbsp;&nbsp;&nbsp;setFrame(fFrame + incFrame);<br />
&nbsp;&nbsp;<b><font color="#000080">end</b></font>;<br />
<b><font color="#000080">end</b></font>;<br />
&nbsp;<br />
<font color="#008000"><i>// Modifica o frame da animação</font></i><br />
<b><font color="#000080">procedure</b></font> TAnimation.setFrame(value: Integer);<br />
<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;fFrame:= value;<br />
&nbsp;&nbsp;<b><font color="#000080">if</b></font> fFrame &lt; <font color="#0000FF">0 </font><b><font color="#000080">then</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;fFrame:= <font color="#0000FF">0</font>;<br />
&nbsp;&nbsp;<b><font color="#000080">if</b></font> fFrame &gt; High(fFrames) <b><font color="#000080">then</b></font><br />
&nbsp;&nbsp;<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;fFrame:= -<font color="#0000FF">1</font>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;fSpeed:= <font color="#0000FF">0</font>;<br />
&nbsp;&nbsp;<b><font color="#000080">end</b></font>;<br />
<b><font color="#000080">end</b></font>;<br />
&nbsp;<br />
<font color="#008000"><i>// Altera a imagem de um dos frames da matriz</font></i><br />
<b><font color="#000080">procedure</b></font> TAnimation.setFrameImage(Index: Integer; value: TBitmap);<br />
<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;<b><font color="#000080">if</b></font> (Index &lt; <font color="#0000FF">0</font>) <b><font color="#000080">or</b></font> (Index &gt; High(fFrames)) <b><font color="#000080">then</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">raise</b></font> Exception.Create(<font color="#0000FF">'Índice da animação fora da faixa permitida.'</font>);<br />
&nbsp;&nbsp;fFrames[Index]:= value;<br />
<b><font color="#000080">end</b></font>;<br />
&nbsp;<br />
<font color="#008000"><i>// Seta os frames da matriz pela matriz de bitmaps passada</font></i><br />
<b><font color="#000080">procedure</b></font> TAnimation.SetFrames(values: <b><font color="#000080">array</b></font> <b><font color="#000080">of</b></font> TBitmap);<br />
<b><font color="#000080">var</b></font><br />
&nbsp;&nbsp;I: Integer;<br />
<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;setLength(fFrames, Length(values));<br />
&nbsp;&nbsp;<b><font color="#000080">for</b></font> I := <font color="#0000FF">0 </font><b><font color="#000080">to</b></font> High(values) <b><font color="#000080">do</b></font><br />
&nbsp;&nbsp;<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;fFrames[I]:= TBitmap.Create;<br />
&nbsp;&nbsp;&nbsp;&nbsp;fFrames[I].Assign(values[I]);<br />
&nbsp;&nbsp;<b><font color="#000080">end</b></font>;<br />
<b><font color="#000080">end</b></font>;<br />
&nbsp;<br />
<font color="#008000"><i>// Atualiza a animação</font></i><br />
<b><font color="#000080">procedure</b></font> TAnimation.Update(lag: Integer);<br />
<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;setDelayed(fDelayed + (lag * fSpeed));<br />
<b><font color="#000080">end</b></font>;</code></p>
<p>&nbsp;&nbsp;&nbsp; Nossa classe agora está criada. É uma classe que pode controlar qualquer animação usando imagens (quadros) no formato bitmap. Para esse tutorial, vamos criar um pequeno programa que mostra várias animações de explosão em lugares aleatórios da tela.</p>
<p>&nbsp;&nbsp;&nbsp; Antes de continuar, faça o download do <a href="http://mottaweb.com.br/files/delphi/animacao.zip">código fonte e imagens da animação aqui</a>.</p>
<p>&nbsp;&nbsp;&nbsp; Agora que você já tem as imagens, vai perceber que elas estão no formato <strong>jpeg</strong> (aliás, um formato que não deve ser usado para animações/sprites), que eu usei aqui só pra reduzir o tamanho do arquivo. =D Mas, enfim, como as imagens estão em <strong>jpeg</strong>, temos três alternativas: A primeira é converter cada imagem manualmente para <strong>bitmap</strong>, já que nossa classe só aceita esse formato. A segunda, é alterar nossa classe para funcionar com imagems em <strong>jpeg</strong> ao invés de <strong>bitmap</strong>, mas como eu disse, jpeg deve ser evitado em animações e sprites. A terceira, é criar uma função para converter as imagens de <strong>jpeg</strong> para <strong>bitmap</strong>. Vamos usar a terceira, já que eu sou um programador <span style='text-decoration:line-through;'>garoto preguiçoso demais para converter as imagens manualmente</span> ^.- </p>
<p><code><font color="#008000"><i>//transforma JPEG em BMP</font></i><br />
<b><font color="#000080">function</b></font> jpeg2bmp(imagem: TJPEGImage): TBitmap;<br />
&nbsp;<br />
<b><font color="#000080">implementation</b></font><br />
&nbsp;<br />
<b><font color="#000080">function</b></font> jpeg2bmp(imagem: TJPEGImage): TBitmap;<br />
<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;<font color="#008000"><i>// instancia o bitmap</font></i><br />
&nbsp;&nbsp;result:= TBitmap.Create;<br />
&nbsp;&nbsp;<font color="#008000"><i>// altera as propriedades (largura/altura) para desenhar a imagem jpeg nele</font></i><br />
&nbsp;&nbsp;result.Width:= imagem.Width;<br />
&nbsp;&nbsp;result.Height:= imagem.Height;<br />
&nbsp;&nbsp;<font color="#008000"><i>// desenha a imagem jpeg no canvas</font></i><br />
&nbsp;&nbsp;result.Canvas.Draw(<font color="#0000FF">0</font>, <font color="#0000FF">0</font>, imagem);<br />
<b><font color="#000080">end</b></font>;</code></p>
<p>&nbsp;&nbsp;&nbsp; Agora nós temos imagens que servem como quadros em nossa classe de animação, podemos começar a criar nosso programa. Primeiro, vamos precisar de algumas variáveis para controlar as animações e, claro, nosso <strong>backbuffer</strong>.</p>
<p><code><b><font color="#000080">var</b></font><br />
&nbsp;&nbsp;Form1: TForm1;<br />
&nbsp;&nbsp;<font color="#008000"><i>// variável do backbuffer</font></i><br />
&nbsp;&nbsp;bbuffer: TBitmap;<br />
&nbsp;<br />
&nbsp;&nbsp;<font color="#008000"><i>// array dos frames usados na animação</font></i><br />
&nbsp;&nbsp;<font color="#008000"><i>// Note que essa variável global só foi adicionada para não carregar</font></i><br />
&nbsp;&nbsp;<font color="#008000"><i>// a mesma animação do HD várias vezes.</font></i><br />
&nbsp;&nbsp;AnimFrames: <b><font color="#000080">array</b></font> <b><font color="#000080">of</b></font> TBitmap;<br />
&nbsp;<br />
&nbsp;&nbsp;<font color="#008000"><i>// Número de frames mostrados.</font></i><br />
&nbsp;&nbsp;Frames: Integer;<br />
&nbsp;&nbsp;<font color="#008000"><i>// Número de frames por segundo.</font></i><br />
&nbsp;&nbsp;FPS: Integer = -<font color="#0000FF">1</font>;<br />
&nbsp;&nbsp;<font color="#008000"><i>// Número de milisegundos para cálculo de FPS.</font></i><br />
&nbsp;&nbsp;FPSTime: Integer;<br />
&nbsp;<br />
&nbsp;&nbsp;<font color="#008000"><i>// Uma lista das animações ativas</font></i><br />
&nbsp;&nbsp;RunningAnims: TList;<br />
&nbsp;<br />
&nbsp;&nbsp;<font color="#008000"><i>// O tempo gasto na última atualização da tela</font></i><br />
&nbsp;&nbsp;<font color="#008000"><i>// Necessário para que as animações rodem em uma velocidade constante,</font></i><br />
&nbsp;&nbsp;<font color="#008000"><i>// independente da velocidade da máquina</font></i><br />
&nbsp;&nbsp;OldTime: Integer = -<font color="#0000FF">1</font>;</code></p>
<p>&nbsp;&nbsp;&nbsp; <strong>AnimFrames</strong> é uma variável útil, já que ela vai permitir carregar as imagens do HD no formato <strong>jpeg</strong> e guardá-las no formato <strong>bitmap</strong>, assim nós só precisamos convertê-las uma vez. Já <strong>RunningAnims</strong> é uma lista com ponteiros para instâncias das animações mostradas na tela. Enfim, nós carregamos as imagens e inicializamos essas variáveis quando o <strong>form</strong> é criado, e liberamos os recursos quando ele é destruído.</p>
<p>&nbsp;&nbsp;&nbsp; Além disso, precisaremos de 2 objetos <strong>TTimer</strong>. Um com o intervalo de 1 milisegundo, que vai controlar a atualização das explosões, e o outro com intervalo de 100 milisegundos, que vai criar animações aleatoriamente na tela.</p>
<p><code><b><font color="#000080">procedure</b></font> TForm1.FormCreate(Sender: TObject);<br />
<b><font color="#000080">var</b></font><br />
&nbsp;&nbsp;I: Integer;<br />
&nbsp;&nbsp;image: TJPEGImage;<br />
<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;randomize;<br />
&nbsp;<br />
&nbsp;&nbsp;<font color="#008000"><i>// Cria o backbuffer</font></i><br />
&nbsp;&nbsp;bbuffer:= TBitmap.Create;<br />
&nbsp;&nbsp;bbuffer.Width:= <font color="#0000FF">640</font>;<br />
&nbsp;&nbsp;bbuffer.Height:= <font color="#0000FF">480</font>;<br />
&nbsp;&nbsp;bbuffer.Canvas.CopyMode:= cmSrcPaint;<br />
&nbsp;&nbsp;bbuffer.Canvas.Brush.Color:= clBlack;<br />
&nbsp;<br />
&nbsp;&nbsp;<font color="#008000"><i>// Carrega a animação do HD</font></i><br />
&nbsp;&nbsp;setLength(AnimFrames, <font color="#0000FF">36</font>);<br />
&nbsp;&nbsp;<b><font color="#000080">for</b></font> I := <font color="#0000FF">0 </font><b><font color="#000080">to</b></font> <font color="#0000FF">35 </font><b><font color="#000080">do</b></font><br />
&nbsp;&nbsp;<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;image:= TJPEGImage.Create;<br />
&nbsp;&nbsp;&nbsp;&nbsp;image.LoadFromFile(<font color="#0000FF">'explosion/screen'</font> + IntToStr(I+<font color="#0000FF">1</font>) + <font color="#0000FF">'.jpg'</font>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;AnimFrames[I]:= jpeg2bmp(image);<br />
&nbsp;&nbsp;&nbsp;&nbsp;FreeAndNil(image); <font color="#008000"><i>// libera a imagem da memória</font></i><br />
&nbsp;&nbsp;<b><font color="#000080">end</b></font>;<br />
&nbsp;<br />
&nbsp;&nbsp;<font color="#008000"><i>// Inicializa a lista de animações</font></i><br />
&nbsp;&nbsp;RunningAnims:= TList.Create;<br />
&nbsp;<br />
&nbsp;&nbsp;<font color="#008000"><i>// Habilita o timer</font></i><br />
&nbsp;&nbsp;Timer1.Enabled:= True;<br />
&nbsp;&nbsp;Timer2.Enabled:= True;<br />
<b><font color="#000080">end</b></font>;<br />
&nbsp;<br />
<font color="#008000"><i>// Destrói o form e libera os recursos</font></i><br />
<b><font color="#000080">procedure</b></font> TForm1.FormDestroy(Sender: TObject);<br />
<b><font color="#000080">var</b></font> i: Integer;<br />
<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;FreeAndNil(bbuffer);<br />
&nbsp;&nbsp;<b><font color="#000080">for</b></font> I := <font color="#0000FF">0 </font><b><font color="#000080">to</b></font> <font color="#0000FF">35 </font><b><font color="#000080">do</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;FreeAndNil(AnimFrames[I]);<br />
<b><font color="#000080">end</b></font>;</code></p>
<p>&nbsp;&nbsp;&nbsp; O modo de cópia <strong>cmSrcPaint</strong> em conjunto com o fundo preto, faz com que a cor preta das imagens desenhadas no <strong>backbuffer</strong> fique transparente.</p>
<p>&nbsp;&nbsp;&nbsp; Agora que inicializamos tudo, falta criar as animações. Então no evento <strong>OnTimer</strong> do <strong>Timer2</strong> vamos colocar um pequeno código que cria animações aleatórias pela tela.</p>
<p><code><font color="#008000"><i>// cria animações em intervalos regulares em posições aleatórias</font></i><br />
<b><font color="#000080">procedure</b></font> TForm1.Timer2Timer(Sender: TObject);<br />
<b><font color="#000080">var</b></font> anim: TAnimation;<br />
<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;<font color="#008000"><i>// instancia a animação</font></i><br />
&nbsp;&nbsp;anim:= TAnimation.Create;<br />
&nbsp;&nbsp;<font color="#008000"><i>// coloca a animação em um lugar aleatório da tela</font></i><br />
&nbsp;&nbsp;anim.X:= Random(ClientWidth);<br />
&nbsp;&nbsp;anim.Y:= Random(ClientHeight);<br />
&nbsp;&nbsp;<font color="#008000"><i>// carrega os frames da matriz AnimFrames na animação</font></i><br />
&nbsp;&nbsp;anim.SetFrames(AnimFrames);<br />
&nbsp;&nbsp;<font color="#008000"><i>// seta um tempo de espera aleatório</font></i><br />
&nbsp;&nbsp;anim.Delay:= random(<font color="#0000FF">10</font>)+<font color="#0000FF">20</font>;<br />
&nbsp;&nbsp;<font color="#008000"><i>// adiciona o ponteiro da instância na lista de animações ativas</font></i><br />
&nbsp;&nbsp;RunningAnims.Add(anim);<br />
<b><font color="#000080">end</b></font>;</code></p>
<p>&nbsp;&nbsp;&nbsp; Por fim, precisamos escrever o código do evento <strong>OnTimer</strong> do <strong>Timer1</strong>, que irá controlar todas as animações ativas na tela. Isso é possível pois temos uma lista de todas as animações ativas guardadas em <strong>RunningAnims</strong>, então basta percorrer esta lista e atualizar as animações nela.</p>
<p><code><font color="#008000"><i>// Timer que controla a atualização da tela</font></i><br />
<b><font color="#000080">procedure</b></font> TForm1.Timer1Timer(Sender: TObject);<br />
<b><font color="#000080">var</b></font><br />
&nbsp;&nbsp;I: Integer;<br />
&nbsp;&nbsp;at: TAnimation;<br />
&nbsp;&nbsp;Lag: Integer;<br />
&nbsp;&nbsp;t: Integer;<br />
<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;<font color="#008000"><i>// como o timer tem um intervalo de 1 milisegundo, esperamos que a tela</font></i><br />
&nbsp;&nbsp;<font color="#008000"><i>// seja atualizada neste intervalo, mas se demorarmos mais para atualizar</font></i><br />
&nbsp;&nbsp;<font color="#008000"><i>// a tela, verifica quanto tempo se passou para que a animação não seja</font></i><br />
&nbsp;&nbsp;<font color="#008000"><i>// prejudicada</font></i><br />
&nbsp;<br />
&nbsp;&nbsp;t:= getTickCount;<br />
&nbsp;&nbsp;<b><font color="#000080">if</b></font> OldTime &lt; <font color="#0000FF">0 </font><b><font color="#000080">then</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;OldTime:= t;<br />
&nbsp;&nbsp;Lag:= (t - OldTime);<br />
&nbsp;&nbsp;OldTime:= t;<br />
&nbsp;&nbsp;<b><font color="#000080">if</b></font> Lag &lt; <font color="#0000FF">0 </font><b><font color="#000080">then</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;Lag:= <font color="#0000FF">1</font>;<br />
&nbsp;&nbsp;I:= <font color="#0000FF">0</font>;<br />
&nbsp;<br />
&nbsp;&nbsp;Inc(FPSTime, Lag);<br />
&nbsp;<br />
&nbsp;&nbsp;<b><font color="#000080">if</b></font> FPSTime &gt; <font color="#0000FF">1000 </font><b><font color="#000080">then</b></font><br />
&nbsp;&nbsp;<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;FPSTime:= FPSTime - <font color="#0000FF">1000</font>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;FPS:= Frames;<br />
&nbsp;&nbsp;&nbsp;&nbsp;Frames:= <font color="#0000FF">0</font>;<br />
&nbsp;&nbsp;<b><font color="#000080">end</b></font>;<br />
&nbsp;<br />
&nbsp;&nbsp;Inc(Frames);<br />
&nbsp;<br />
&nbsp;&nbsp;<b><font color="#000080">if</b></font> FPS &gt; -<font color="#0000FF">1 </font><b><font color="#000080">then</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;caption:= <font color="#0000FF">'Parte IV - Animações - FPS: '</font> + &nbsp;IntToStr(FPS);<br />
&nbsp;<br />
&nbsp;&nbsp;<font color="#008000"><i>// limpa o canvas</font></i><br />
&nbsp;&nbsp;bbuffer.Canvas.FillRect(Rect(<font color="#0000FF">0</font>,<font color="#0000FF">0</font>,<font color="#0000FF">640</font>,<font color="#0000FF">480</font>));<br />
&nbsp;<br />
&nbsp;&nbsp;<font color="#008000"><i>// desenha todas as animações da lista</font></i><br />
&nbsp;&nbsp;<b><font color="#000080">while</b></font> I &lt; RunningAnims.Count-<font color="#0000FF">1 </font><b><font color="#000080">do</b></font><br />
&nbsp;&nbsp;<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;at:= TAnimation(RunningAnims.Items[I]);<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000"><i>// se a animação tiver acabado, retira ela da lista</font></i><br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">if</b></font> at.fFrame = -<font color="#0000FF">1 </font><b><font color="#000080">then</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RunningAnims.Remove(at);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FreeAndNil(at);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">end</b></font><br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000"><i>// do contrário, atualiza e desenha a animação</font></i><br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">else</b></font> <b><font color="#000080">begin</b></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at.Update(lag);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at.Paint(bbuffer.Canvas);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Inc(I);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<b><font color="#000080">end</b></font>;<br />
&nbsp;&nbsp;<b><font color="#000080">end</b></font>;<br />
&nbsp;<br />
&nbsp;&nbsp;<font color="#008000"><i>// envia o backbuffer pra tela</font></i><br />
&nbsp;&nbsp;Canvas.Draw(<font color="#0000FF">0</font>,<font color="#0000FF">0</font>, bbuffer);<br />
<b><font color="#000080">end</b></font>;</code></p>
<p>&nbsp;&nbsp;&nbsp; Para ver o efeito das animações basta rodar o programa e voílà! Você deve ver várias animações sendo criadas aleatóriamente pela tela em intervalos regulares.</p>
<p><b>- Conclusão -</b></p>
<p>&nbsp;&nbsp;&nbsp; Esse foi um pequeno tutorial para desenvolvimento de jogos em Delphi, utilizando apenas a <strong>GDI</strong> do Windows. Claro, você não deve utilizar a GDI do Windows para desenvolver jogos, mas o conceito aqui se aplica a qualquer outra framework. Eu pretendo escrever mais tutoriais de GameDev em Delphi, utilizando frameworks como <strong><a href="http://www.afterwarp.net/">Asphyre</a></strong> e <strong><a href="http://www.delphi-jedi.org/">SDL</a></strong> (apesar de estar um pouco mais ocupado agora i.i). Até lá o(^-^)/&#8221;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/undercode.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/undercode.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/undercode.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/undercode.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/undercode.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/undercode.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/undercode.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/undercode.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/undercode.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/undercode.wordpress.com/68/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=undercode.wordpress.com&blog=3870490&post=68&subd=undercode&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://undercode.wordpress.com/2009/03/09/criando-jogos-em-delphi-parte-iv/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f9c280863bd9c210358b04e6e98d82fb?s=96&#38;d=wavatar" medium="image">
			<media:title type="html">.killdream</media:title>
		</media:content>
	</item>
	</channel>
</rss>