<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1115864231576611699</id><updated>2012-02-14T23:01:21.430-02:00</updated><category term='computação gráfica'/><category term='lazarus'/><category term='campo minado'/><category term='partículas'/><category term='SDL'/><category term='sistema de partículas'/><category term='AlphaBlend'/><category term='glscene'/><category term='transparência'/><category term='game'/><category term='animação'/><category term='openGL'/><category term='delphi'/><title type='text'>Computação Gráfica e Jogos em Delphi</title><subtitle type='html'>Artigos, pesquisas, tutoriais e projetos multimídia desenvolvidos em object pascal.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://delphigames.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://delphigames.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Fabiano Salles</name><uri>http://www.blogger.com/profile/06349830371007868936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_TMF2yTWTSl0/SGOIwxW72LI/AAAAAAAAADs/_1RXXbnFwwg/S220/fabiano-01.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1115864231576611699.post-114258316193733860</id><published>2011-09-15T00:41:00.000-03:00</published><updated>2011-09-15T00:49:37.596-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='glscene'/><category scheme='http://www.blogger.com/atom/ns#' term='openGL'/><title type='text'>GLScene Super Guia Um livro grauito e em português sobre o GLScene</title><content type='html'>&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-wCBybiP7lXs/TnFuHsh5u4I/AAAAAAAAAJA/3wauUTJO6Ec/s1600/MiniWorld.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="137" src="http://1.bp.blogspot.com/-wCBybiP7lXs/TnFuHsh5u4I/AAAAAAAAAJA/3wauUTJO6Ec/s200/MiniWorld.png" width="200" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Mini Mundo, um dos demos &lt;br /&gt;que acompanham o livro&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Jerson Seling, um cientista da computação gaúcho, publicou há uma tempo atrás, em seu site, os links para download de um livro de sua autoria sobre GLScene chamado: GLScene Super Guia.&lt;br /&gt;&lt;br /&gt;O livro está organizado como uma série, bem ordenada, de artigos cobrindo desde a configuração de uma cena básica até tópicos avançados como integração com frameworks de física (Newton e ODE), passando por temas úteis como elementos gráficos 2D em cenas 3D, raycasting, setup de materais, criação de objetos em runtime e carregamento de cenários modelados em outros programas.&lt;br /&gt;&lt;br /&gt;Para quem está interessado em começar a utilizar este excelente framework, fica aí a dica do livro de nosso camarada gaúcho.&lt;br /&gt;&lt;br /&gt;O GLScene está em pleno desenvolvimento e é compatível com todas as versões 5, 6, 7, 2005, 2006, 2007, 2009, 2010, XE e até a recém lançada XE2!&lt;br /&gt;&lt;br /&gt;Links&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://jersonseling.wikispaces.com/GLScene" target="_blank"&gt;Página do Jserson Seling (download do livro)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sourceforge.net/projects/glscene/" target="_blank"&gt;Página do GLScene no Source Force&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sourceforge.net/projects/glscene/forums/forum/93605" target="_blank"&gt;Fórum oficial do GLScene&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1115864231576611699-114258316193733860?l=delphigames.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphigames.blogspot.com/feeds/114258316193733860/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1115864231576611699&amp;postID=114258316193733860' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/114258316193733860'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/114258316193733860'/><link rel='alternate' type='text/html' href='http://delphigames.blogspot.com/2011/09/glscene-super-guia-um-livro-grauito-e.html' title='GLScene Super Guia &lt;br/&gt;&lt;small&gt;&lt;i&gt;Um livro grauito e em português sobre o GLScene&lt;/small&gt;&lt;/i&gt;'/><author><name>Fabiano Salles</name><uri>http://www.blogger.com/profile/06349830371007868936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_TMF2yTWTSl0/SGOIwxW72LI/AAAAAAAAADs/_1RXXbnFwwg/S220/fabiano-01.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-wCBybiP7lXs/TnFuHsh5u4I/AAAAAAAAAJA/3wauUTJO6Ec/s72-c/MiniWorld.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1115864231576611699.post-2282141596622809081</id><published>2011-08-29T00:00:00.007-03:00</published><updated>2011-09-17T00:02:09.745-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='glscene'/><category scheme='http://www.blogger.com/atom/ns#' term='lazarus'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>A Magnetic AdventureUm game de física escrito no Lazarus</title><content type='html'>&lt;iframe allowfullscreen="" frameborder="0" height="350" src="http://www.youtube.com/embed/4c_uybAJM-A" width="100%"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;O jogo &lt;a href="http://www.youdagames.com/A-Magnetic-Adventure-game-info-4990" target="_blank"&gt;A Magnetic Adventure&lt;/a&gt; não é exatamente novo (seu release aconteceu em outubro de 2010), mas hoje, num fórum de OpenGL, eu tive a grata surpresa de descobrir que ele foi escrito inteiramente em pascal.&lt;br /&gt;&lt;br /&gt;Para ser mais exato, ele foi feito usando o &lt;a href="http://www.lazarus.freepascal.org/" target="_blank"&gt;Lazarus&lt;/a&gt;&amp;nbsp;para a programação, &lt;a href="http://sourceforge.net/projects/glscene/" target="_blank"&gt;GLScene&lt;/a&gt; para os gráficos e os bindings do Box2D para calcular a física. E a física é o ponto alto do jogo.&lt;br /&gt;&lt;br /&gt;O jogador controla um ímã para interagir com as partes metálicas de curiosos mecanismos que guardam "totens" que o personagem precisa alcançar para concluir cada um dos 50 níveis disponíveis.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Com um visual muito bem trabalhado para um jogo casual, um motor de física convincente, e um preço muito convidativo ( US$ 4,95 ), não há como não recomendar este título que tem tudo para agradar os jogadores casuais e os programadores que queiram ver que é possível criar muito mais que aplicações corporativas nesta grande linguagem.&lt;br /&gt;&lt;br /&gt;Tanto a versão de demonstração como a versão completa, somente para windows, podem ser encontradas em &lt;a href="http://www.youdagames.com/A-Magnetic-Adventure-game-info-4990" target="_blank"&gt;aqui&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Divirtam-se!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1115864231576611699-2282141596622809081?l=delphigames.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphigames.blogspot.com/feeds/2282141596622809081/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1115864231576611699&amp;postID=2282141596622809081' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/2282141596622809081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/2282141596622809081'/><link rel='alternate' type='text/html' href='http://delphigames.blogspot.com/2011/08/magnetic-adventure.html' title='A Magnetic Adventure&lt;br&gt;&lt;small&gt;&lt;i&gt;Um game de física escrito no Lazarus&lt;/i&gt;&lt;/small&gt;'/><author><name>Fabiano Salles</name><uri>http://www.blogger.com/profile/06349830371007868936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_TMF2yTWTSl0/SGOIwxW72LI/AAAAAAAAADs/_1RXXbnFwwg/S220/fabiano-01.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/4c_uybAJM-A/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1115864231576611699.post-6315003752125846414</id><published>2011-06-29T18:14:00.000-03:00</published><updated>2011-06-29T18:14:57.492-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>Gráficos Higth Tech "Made in Delphi"</title><content type='html'>&lt;iframe allowfullscreen="" frameborder="0" height="350" src="http://www.youtube.com/embed/fEK808gC1GM" width="100%"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;Faz um tempo que venho acompanhando o blog de um norueguês chamado Rick, que fala sobre o andamento de um projeto de um jogo chamado &lt;a href="http://tower22.blogspot.com/"&gt;Tower22&lt;/a&gt;, um jogo de horror pessoal desenvolvido do zero usando o Delphi 7.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Já vi muitos projetos de jogos independentes serem iniciados e abandonados antes de produzir algo minimamente demonstrável. Por isso, talvez, o &lt;a href="http://tower22.blogspot.com/"&gt;Tower22&lt;/a&gt; tenha um charme especial afinal, o que esse cara tem feito é mesmo de impressionar. Partido de uma aplicação normal (eu já falei que o cara usa &lt;i&gt;Delphi 7&lt;/i&gt;?), ele construiu uma engine 3D completa com todos os recursos que um motor gráfico moderno deve ter: bloom, HDR, pixel shading, ambient ligth... basta olhar o vídeo aí em cima pra ter uma idéia do que eu tô falando.&lt;br /&gt;&lt;br /&gt;Fica aí a dica para quem anda querendo se envolver num projeto indie sério: o Rick está buscando colaboradores para trabalhar no motor de física da engine.&lt;br /&gt;&lt;br /&gt;Alguém se habilita?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Links&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://tower22.blogspot.com/"&gt;Blog do projeto Tower 22&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://tower22.blogspot.com/2010/01/targets-battleplan.html"&gt;Página do "roadmap" do projeto&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1115864231576611699-6315003752125846414?l=delphigames.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphigames.blogspot.com/feeds/6315003752125846414/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1115864231576611699&amp;postID=6315003752125846414' title='3 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/6315003752125846414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/6315003752125846414'/><link rel='alternate' type='text/html' href='http://delphigames.blogspot.com/2011/06/graficos-higth-tech-made-in-delphi.html' title='Gráficos Higth Tech &quot;Made in Delphi&quot;'/><author><name>Fabiano Salles</name><uri>http://www.blogger.com/profile/06349830371007868936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_TMF2yTWTSl0/SGOIwxW72LI/AAAAAAAAADs/_1RXXbnFwwg/S220/fabiano-01.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/fEK808gC1GM/default.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1115864231576611699.post-2247127716914335809</id><published>2010-04-19T15:26:00.004-03:00</published><updated>2010-04-19T16:14:48.555-03:00</updated><title type='text'>Pascal Gamer Magazine</title><content type='html'>Acaba de sair o segundo exemplar da revista eletrônica "Pascal Gamer Magazine".&lt;br /&gt;&lt;br /&gt;Para quem não conheçe, a revista é o resultado de uma iniciativa de Jason McMillen, um programador declaradamente apaixonado pela linguagem pascal que e conta com a ajuda de veteranos do mundo indie, como Dominique Loius (administrador do site &lt;a href="http://www.sulaco.co.za/"&gt;Sulaco&lt;/a&gt;) e Christina Warne (administradora do &lt;a href="http://www.pascalgamedevelopment.com/"&gt;Pascal Game Development&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Nesta edição, o foco da revista está voltado para o resultado do Concurso Anual de Jogos em Pascal, o &lt;a href="http://www.pgdannual.com/"&gt;PGD&lt;/a&gt;, um dos eventos mais significativo da modesta comunidade de desenvolvedores indie que utilizam o bom e velho pascal como linguagem.&lt;br /&gt;Além do assunto da capa, a seção "The Coder's Block" merece atenção por tratar de um do assuntos mais difícies para quem está começando: a matemática 3D.&lt;br /&gt;&lt;br /&gt;Quem quiser conferir, pode acessar e baixar gratuitamente o exemplar em&lt;a href="http://pascalgamer.com/"&gt; http://pascalgamer.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1115864231576611699-2247127716914335809?l=delphigames.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphigames.blogspot.com/feeds/2247127716914335809/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1115864231576611699&amp;postID=2247127716914335809' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/2247127716914335809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/2247127716914335809'/><link rel='alternate' type='text/html' href='http://delphigames.blogspot.com/2010/04/pascal-magazine.html' title='Pascal Gamer Magazine'/><author><name>Fabiano Salles</name><uri>http://www.blogger.com/profile/06349830371007868936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_TMF2yTWTSl0/SGOIwxW72LI/AAAAAAAAADs/_1RXXbnFwwg/S220/fabiano-01.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1115864231576611699.post-1135493976073398059</id><published>2010-04-12T11:57:00.002-03:00</published><updated>2010-04-12T11:59:00.886-03:00</updated><title type='text'>Migração de Servidor Concluída</title><content type='html'>A migração dos arquivos para o novo servidor foi concluída!&lt;br /&gt;Todos os links para código-fontes e executáveis já estão funcionando.&lt;br /&gt;&lt;br /&gt;Evoé...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1115864231576611699-1135493976073398059?l=delphigames.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphigames.blogspot.com/feeds/1135493976073398059/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1115864231576611699&amp;postID=1135493976073398059' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/1135493976073398059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/1135493976073398059'/><link rel='alternate' type='text/html' href='http://delphigames.blogspot.com/2010/04/migracao-de-servidor-concluida.html' title='Migração de Servidor Concluída'/><author><name>Fabiano Salles</name><uri>http://www.blogger.com/profile/06349830371007868936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_TMF2yTWTSl0/SGOIwxW72LI/AAAAAAAAADs/_1RXXbnFwwg/S220/fabiano-01.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1115864231576611699.post-8195879647335904448</id><published>2010-04-08T12:23:00.002-03:00</published><updated>2010-04-08T12:27:12.910-03:00</updated><title type='text'>Migração de Servidor</title><content type='html'>Estou migrando os arquivos do blog para um novo servidor.&lt;br /&gt;Caso algum link estaja quebrado, por favor, me avise em fabiano.salles@gmail.com que corrigirei o mais vreve possível.&lt;br /&gt;Até este sábado, dia 10, a migração estará concluída.&lt;br /&gt;&lt;br /&gt;Abraços.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1115864231576611699-8195879647335904448?l=delphigames.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphigames.blogspot.com/feeds/8195879647335904448/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1115864231576611699&amp;postID=8195879647335904448' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/8195879647335904448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/8195879647335904448'/><link rel='alternate' type='text/html' href='http://delphigames.blogspot.com/2010/04/migracao-de.html' title='Migração de Servidor'/><author><name>Fabiano Salles</name><uri>http://www.blogger.com/profile/06349830371007868936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_TMF2yTWTSl0/SGOIwxW72LI/AAAAAAAAADs/_1RXXbnFwwg/S220/fabiano-01.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1115864231576611699.post-5005272341396601802</id><published>2009-08-17T12:18:00.005-03:00</published><updated>2009-08-18T10:13:48.012-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='SDL'/><category scheme='http://www.blogger.com/atom/ns#' term='openGL'/><title type='text'>Alguns Jogos criados em Delphi</title><content type='html'>&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/aTyYM12YRew&amp;amp;hl=pt-br&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/aTyYM12YRew&amp;amp;hl=pt-br&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;p&gt;Muita gente, talvez por falta de conhecimento, ou da escassez de títulos comerciais produzidos na ferramenta da CodeGear, duvida da capacidade do Delphi na produção e jogos e simulações de alto desempenho.&lt;/p&gt;&lt;p&gt;É verdade que o C++ impera na indústria, seja nos consoles, nos portáteis, nos celulares (aqui, dividindo o espaço com o Java 2 Mircro Edition, e nos desktops mas, isto se deve muito mais à onipresença de bons compiladores C/C++ nos dispositivos eletrônicos que à (inegável) qualidade técnica da liguagem. Mas, ora! O que o há no C++ que nós não temos em object-pascal? Temos suporte a sobrecarga de operadores, suporte a programação genérica, RTTI, Unicode, integração transparente com Win32 API, DirectX, OpenGL, SDL, acesso dierto ao hardware via inline assembly, compilação para Mac, Linux, GameBoy, XBox (via XNA e crhome) e, finalmente, com a versão 2010, teremos compilação nativa para chips de 64bits!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Todos os jogos dos vídeos foram feitos por hobistas utilizando delphi e/ou free pascal. Alguém ainda duvida?&lt;/p&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/jEEmwZkqmpM&amp;hl=pt-br&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/jEEmwZkqmpM&amp;hl=pt-br&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/BGxgpfGcWmY&amp;hl=pt-br&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/BGxgpfGcWmY&amp;hl=pt-br&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1115864231576611699-5005272341396601802?l=delphigames.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphigames.blogspot.com/feeds/5005272341396601802/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1115864231576611699&amp;postID=5005272341396601802' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/5005272341396601802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/5005272341396601802'/><link rel='alternate' type='text/html' href='http://delphigames.blogspot.com/2009/08/alguns-jogos-criados-em-delphi.html' title='Alguns Jogos criados em Delphi'/><author><name>Fabiano Salles</name><uri>http://www.blogger.com/profile/06349830371007868936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_TMF2yTWTSl0/SGOIwxW72LI/AAAAAAAAADs/_1RXXbnFwwg/S220/fabiano-01.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1115864231576611699.post-1508683178438313964</id><published>2009-07-28T18:02:00.018-03:00</published><updated>2010-11-24T13:16:24.477-02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='transparência'/><category scheme='http://www.blogger.com/atom/ns#' term='delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='animação'/><category scheme='http://www.blogger.com/atom/ns#' term='computação gráfica'/><category scheme='http://www.blogger.com/atom/ns#' term='AlphaBlend'/><title type='text'>Animações em tempo real com a VCL - Parte IV</title><content type='html'>&lt;blockquote&gt;No artigo anterior, criamos uma animação procedural, onde com um algoritmo simples, um padrão de cores foi gerado. Neste artigo vamos criar um efeito sobre uma imagem já existente utilizando um conceito simples de transparência.&lt;/blockquote&gt;&lt;br /&gt;&lt;h3&gt;Opacidade&lt;/h3&gt;Segundo o Wikipedia:&lt;br /&gt;&lt;blockquote&gt;A opacidade é uma propriedade óptica da matéria. Um material é considerado opaco quando não permite a passagem da luz em quantidades apreciáveis. Geralmente, diz-se que um material é opaco quando bloqueia a passagem da luz visível. (&lt;a href="http://pt.wikipedia.org/wiki/Opacidade"&gt;http://pt.wikipedia.org/wiki/Opacidade&lt;/a&gt;)&lt;/blockquote&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_TMF2yTWTSl0/Sm9vX1cP3rI/AAAAAAAAAHI/CHGZEPyKca8/s1600-h/art01.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5363628136494784178" src="http://4.bp.blogspot.com/_TMF2yTWTSl0/Sm9vX1cP3rI/AAAAAAAAAHI/CHGZEPyKca8/s200/art01.png" style="cursor: pointer; float: left; height: 156px; margin: 0pt 10px 10px 0pt; width: 200px;" /&gt;&lt;/a&gt;Para nossos estudos, vamos definir opacidade como sendo o nível de transparência de uma imagem cujo valor será representado por um byte, o que nos dá uma faixa de &lt;code&gt;256&lt;/code&gt; valores possíveis (&lt;code&gt;0..255&lt;/code&gt;) onde &lt;code&gt;0&lt;/code&gt; define uma imagem completamente transparente e &lt;code&gt;255&lt;/code&gt; uma imagem completamente opaca.&lt;br /&gt;Vamos criar um descendente de TBitmap onde adicionaremos esta propriedade.&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre class="delphi" name="code"&gt;TSprite = class(TBitmap)&lt;br /&gt;private&lt;br /&gt;FOpacity: byte;&lt;br /&gt;procedure SetOpacity(const Value: byte);&lt;br /&gt;published&lt;br /&gt;property Opacity: byte read FOpacity write SetOpacity; &lt;br /&gt;end;&lt;/pre&gt;Agora vamos instanciar nosso sprite na inicialização do programa (lembrando que estamos modificando o código do template cirado nos artigos anteriores)&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre class="delphi" name="code"&gt;procedure TForm1.FormCreate(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;ReportMemoryLeaksOnShutdown := True;&lt;br /&gt;ClientWidth   := 800;               &lt;br /&gt;ClientHeight  := 600;               &lt;br /&gt;fOffScreen := TBitmap.Create;       &lt;br /&gt;fOffScreen.PixelFormat := pf24bit;  &lt;br /&gt;fOffScreen.Width  := ClientWidth;   &lt;br /&gt;fOffScreen.Height := ClientHeight;  &lt;br /&gt;fOffScreen.Canvas.Font.Color := clGray;&lt;br /&gt;fOffScreen.Canvas.Font.Size  := 9;&lt;br /&gt;&lt;br /&gt;sprite := TSprite.Create;&lt;br /&gt;sprite.LoadFromFile('img01.bmp');&lt;br /&gt;sprite.Opacity := MAXBYTE div 2;&lt;br /&gt;Application.OnIdle := OnIdle;&lt;br /&gt;end;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Windows.AlphaBlend&lt;/h3&gt;Existe uma função na API do windows chamada AlphaBlend que serve para exibir imagens que possuem informações de transparência. Vamos utilizá-la para renderizar nosso sprite com &lt;code&gt;50%&lt;/code&gt; de opacidade sobre um background preto (note que já configuramos opacidade como &lt;code&gt;MAXBYTE div 2&lt;/code&gt;).&lt;br /&gt;A primeira coisa que precisamos para usar o Windows.AlphaBlend é configurar um registro do tipo TBlendFunction (Veja a &lt;a href="http://msdn.microsoft.com/en-us/library/aa921335.aspx"&gt;descrição oficial&lt;/a&gt; deste struct no MSDN).&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre class="delphi" name="code"&gt;procedure TForm1.DrawToBuffer;&lt;br /&gt;var&lt;br /&gt;Canvas : TCanvas;&lt;br /&gt;Blendf : TBlendFunction;&lt;br /&gt;begin&lt;br /&gt;Canvas := fOffScreen.Canvas;&lt;br /&gt;Canvas.Brush.Color := clBlack;&lt;br /&gt;Canvas.FillRect(fOffScreen.Canvas.ClipRect);&lt;br /&gt;&lt;br /&gt;Blendf.BlendOp    := AC_SRC_OVER;&lt;br /&gt;Blendf.BlendFlags := 0;&lt;br /&gt;Blendf.SourceConstantAlpha := sprite.Opacity;&lt;br /&gt;Blendf.AlphaFormat := AC_SRC_OVER;&lt;br /&gt;end;&lt;/pre&gt;O parâmetro &lt;code&gt;BlendOp&lt;/code&gt; representa a opração de mesclagem a executar. Como queremos copiar nosso sprite “por cima” da imagem de fundo, setamos &lt;code&gt;BlendOP&lt;/code&gt; com a constante &lt;code&gt;AC_SRC_OVER&lt;/code&gt;.&lt;br /&gt;O parâmatro &lt;code&gt;BlendFlags&lt;/code&gt; deve ser sempre zero.&lt;br /&gt;&lt;code&gt;SourceConstantAlpha&lt;/code&gt; define um valor de transparência a ser aplicado na imagem de origem. Aqui, simplesmente passamos o valor da opacidade de nosso sprite.&lt;br /&gt;Por fim, &lt;code&gt;AlphaFormat&lt;/code&gt; deve ser &lt;code&gt;AC_SRC_OVER&lt;/code&gt; para que o Windows não tente buscar informações de transparência nos pixels da imagem de origem, aplicando em vez disto, o valor de &lt;code&gt;SourceConstantAlpha&lt;/code&gt;.&lt;br /&gt;Pronto. Com nosso &lt;code&gt;TBlendFunction&lt;/code&gt; configurado, podemos desenhar o sprite semi-transparente. Complemente o método &lt;code&gt;DrawToBuffer&lt;/code&gt; conforme a listagem abaixo e execute o programa para ver o resultado.&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre class="delphi" name="code"&gt;procedure TForm1.DrawToBuffer;&lt;br /&gt;var&lt;br /&gt;Canvas : TCanvas;&lt;br /&gt;Blendf : TBlendFunction;&lt;br /&gt;begin&lt;br /&gt;Canvas := fOffScreen.Canvas;&lt;br /&gt;Canvas.Brush.Color := clBlack;&lt;br /&gt;Canvas.FillRect(fOffScreen.Canvas.ClipRect);&lt;br /&gt;&lt;br /&gt;Blendf.BlendOp    := AC_SRC_OVER;&lt;br /&gt;Blendf.BlendFlags := 0;&lt;br /&gt;Blendf.SourceConstantAlpha := sprite.Opacity;&lt;br /&gt;Blendf.AlphaFormat := AC_SRC_OVER;&lt;br /&gt;&lt;br /&gt;Windows.AlphaBlend(&lt;br /&gt;Canvas.Handle,  {manipulador da imagem de destino}&lt;br /&gt;fOffScreen.Width - sprite.Width, {coordenada X}&lt;br /&gt;0,                               {coordenada Y}&lt;br /&gt;sprite.Width,                    {largura da área de desenho}&lt;br /&gt;sprite.Height,                   {altura da área de desenho}&lt;br /&gt;&lt;br /&gt;sprite.Canvas.Handle, {manipulador da imagem de origem}&lt;br /&gt;0,                    {coordenada X}&lt;br /&gt;0,                    {coordenada Y}&lt;br /&gt;sprite.Width,         {largura da imagem de origem}&lt;br /&gt;sprite.Height,        {altura da imagem de origem}&lt;br /&gt;&lt;br /&gt;Blendf                 {parâmetros de executação(TBlendFunction)}&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;Canvas.TextOut(10, 10, Format('Opacidade : %d', [sprite.Opacity]));&lt;br /&gt;end;&lt;/pre&gt;Se tudo estiver certo, você vai ver uma imagem no canto esquerdo da tela de seu programa. A imagem parece muito escura porque metade a luminosidade foi misturada com o fundo negro. Altere o valor de opacidade do sprite para chegar a resultados diferentes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Fade In e Fade Out&lt;/h3&gt;Uma aplicação muito comum da opacidade em imagens é a criação dos efeitos Fade In e Fade Out. Em um (fade in) uma imagem vai surgindo aos poucos até ficar completamente visível, no outro (fade out) a imagem vai se apagando até sumir completamente. Com o que já temos até aqui, é realmente muito fácil implementar estes efeitos: basta ir alterando o valor da propriedade &lt;code&gt;Opacity&lt;/code&gt; ao longo do tempo. Vejamos como ficará o método UpdateAnimation.&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre class="delphi" name="code"&gt;procedure TForm1.UpdateAnimation;&lt;br /&gt;begin&lt;br /&gt;if OpIncreasing then&lt;br /&gt;sprite.Opacity := sprite.Opacity + 1&lt;br /&gt;else&lt;br /&gt;sprite.Opacity := sprite.Opacity - 1;&lt;br /&gt;&lt;br /&gt;case sprite.Opacity of&lt;br /&gt;0   : OpIncreasing := true;&lt;br /&gt;255 : OpIncreasing := false;&lt;br /&gt;end;&lt;br /&gt;end;&lt;/pre&gt;Execute o programa e veja os efeitos em funcionamento. Para conseguir novos efeitos, altere os valores dos incrementos e decrementos em cada iteração.&lt;br /&gt;Até o próximo post.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Downloads&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Imagem 50% opaca: &lt;a href="http://fabianosalles.eti.br/blog/delphi/files/animacoes/AnimacoesIV-src-a.zip"&gt;Código fonte&lt;/a&gt; | &lt;a href="http://fabianosalles.eti.br/blog/delphi/files/animacoes/AnimacoesIV-bin-a.zip"&gt;executável&lt;/a&gt;&lt;/li&gt;&lt;li&gt;FadeIn e FadeOut: &lt;a href="http://fabianosalles.eti.br/blog/delphi/files/animacoes/AnimacoesIV-src-b.zip"&gt;Código fonte&lt;/a&gt; | &lt;a href="http://fabianosalles.eti.br/blog/delphi/files/animacoes/AnimacoesIV-bin-b.zip"&gt;executável&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1115864231576611699-1508683178438313964?l=delphigames.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphigames.blogspot.com/feeds/1508683178438313964/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1115864231576611699&amp;postID=1508683178438313964' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/1508683178438313964'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/1508683178438313964'/><link rel='alternate' type='text/html' href='http://delphigames.blogspot.com/2009/07/animacoes-em-tempo-real-com-vcl-parte_28.html' title='Animações em tempo real com a VCL - Parte IV'/><author><name>Fabiano Salles</name><uri>http://www.blogger.com/profile/06349830371007868936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_TMF2yTWTSl0/SGOIwxW72LI/AAAAAAAAADs/_1RXXbnFwwg/S220/fabiano-01.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_TMF2yTWTSl0/Sm9vX1cP3rI/AAAAAAAAAHI/CHGZEPyKca8/s72-c/art01.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1115864231576611699.post-3871701258502540248</id><published>2009-07-25T13:16:00.027-03:00</published><updated>2009-07-25T15:45:38.169-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='animação'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>Animações em tempo real com a VCL - Parte III</title><content type='html'>&lt;blockquote&gt;No artigo anterior, configuramos um formulário padrão da VCL para que pudéssemos exibir animações em sua superfície. Criamos também uma bola, que podíamos manipular pelas setas do teclado e fazê-la se mover pela tela. Nesta parte, vamos falar um pouco de teoria e criar nossa primeira animação procedural.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Um pouco de teoria&lt;/h3&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_TMF2yTWTSl0/Sms5KnQE7KI/AAAAAAAAAHA/HH3bcJh8hBo/s1600-h/01.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 200px; height: 158px;" src="http://4.bp.blogspot.com/_TMF2yTWTSl0/Sms5KnQE7KI/AAAAAAAAAHA/HH3bcJh8hBo/s200/01.jpg" alt="" id="BLOGGER_PHOTO_ID_5362442635812596898" border="0" /&gt;&lt;/a&gt;O sistema ocular humano é limitado quanto ao espectro visível de luz e quanto à &lt;a href="http://www.scielo.br/pdf/abo/v65n6/13823.pdf"&gt;velocidade de interpretação&lt;/a&gt; das imagens. O cérebro, porém, é muito bom no trabalho de contornar estas limitações e nos fazer enxergar imagens corretas, nítidas e sem quebras. Mas este trabalho de interpretação está sujeito a falhas e são essas falhas de interpretação que causam as famosas &lt;a href="http://pt.wikipedia.org/wiki/Ilus%C3%A3o_de_%C3%B3ptica"&gt;ilusões de ótica&lt;/a&gt;. A animação por computador é um tipo de ilusão projetada para causar ao o observador a impressão de movimento.&lt;/p&gt;&lt;p&gt;Desde o surgimento da animação, o seu fundamento é o mesmo: exibir uma seqüência de imagens estáticas, ligeiramente diferentes entre si, numa a uma velocidade superior a 12 imagens por segundo. Quando isto acontece, o olho envia as imagens paradas ao cérebro, mas este acha que se trata de um objeto animado e une-as, criando os pedaços que faltam para que se tenha a impressão de se estar vendo um objeto animado. Muito embora, não pareça haver um consenso entre os cientistas sobre quantos quadros por segundo são necessários para que a “ilusão da animação” aconteça, 12 quadros parecem ser suficientes para que a maioria dos seres humanos visualize-os como uma animação.&lt;/p&gt;&lt;p&gt;A TV, o cinema, o computador, os desenhos animados e os jogos eletrônicos são todos construídos em cima desta idéia. O sistema &lt;a href="http://pt.wikipedia.org/wiki/PAL-M"&gt;PAL-M&lt;/a&gt; usado no Brasil usa uma taxa de 30fps (do inglês Frames per Second, literalmente quadros por segundo, é a unidade medida padrão usada na indústria e, portanto iremos utilizá-la de agora em diante), filmes em DVD de boa qualidade usam de 24 a 30fps e, na animação de jogos para computador, uma taxa ideal de 60fps vem se estabelecendo ao longo dos anos.&lt;br /&gt;Quando digo “taxa ideal”, não estou afirmando que é necessário alcançar os 60fps ou que seja errado ultrapassá-los. Na realidade, quanto mais quadros por segundo você puder exibir, mais convincente e suave será sua animação, então, daqui pra frente, vamos escrever nossos programas para que alcancem a maior taxa de fps que conseguirmos.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;A composição das cores&lt;/h3&gt;&lt;p&gt;Como sabemos, tudo que enxergamos é luz. Os objetos que vemos são, na realidade, luz refletida e/ou emitida por suas superfícies. Sabemos também que a partir da mistura de umas poucas cores primárias, todas as outras cores podem ser obtidas. Pois bem, nos monitores de computador, todas as cores são formadas a partir da combinação de apenas três cores: o vermelho (red), o verde (green) e o azul (blue), o famoso &lt;span style="font-weight: bold;"&gt;padrão &lt;span style="color: rgb(255, 0, 0);"&gt;R&lt;/span&gt;&lt;span style="color: rgb(51, 204, 0);"&gt;G&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;B&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;Neste formato, utilizado exclusivamente por dispositivos emissores de luz, quando todos os três componentes RGB estão em 0% de sua intensidade obtém-se a cor preta e, no caso inverso, quando todos os três componentes estão em 100%, obtém-se a cor branca. Todas as outras cores são obtidas ao se combinar porções distintas de cada um destes componentes.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Imagens, bitmaps e Pixels&lt;/h3&gt;&lt;p&gt;Como dito antes, toda imagem digital é um conjunto de pixels. Pra ser mais preciso, podemos defini-las como sendo uma matriz de pixels que é mapeada, pixel a pixel, para um dispositivo de saída (monitor, plotter, impressora, etc).&lt;/p&gt;&lt;p&gt;Nos primórdios da computação, quando os monitores eram monocromáticos, as imagens eram simplesmente uma seqüência de bits que dizia se um ponto numa determinada coordenada no monitor deveria estar acesa ou apagada. Um &lt;a href="http://www.ic.uff.br/%7Eaconci/curso/FormatoBMP.htm"&gt;mapa de bits&lt;/a&gt;, um bitmap.&lt;/p&gt;&lt;p&gt;O Windows utiliza este conceito para &lt;a href="http://www.ic.uff.br/%7Eaconci/curso/bmp.pdf"&gt;representar tudo o que deve aparecer no monitor&lt;/a&gt;. Ele sempre mantém uma imagem do tipo bitmap em uma área especial da memória RAM que o sistema de vídeo usa para montar a imagem final na tela. A este espaço dá-se o nome de &lt;a href="http://www.baixaki.com.br/info/1421-o-que-e-frame-buffer.htm"&gt;frame buffer&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;O Delphi, através da classe &lt;code&gt;TBitmap&lt;/code&gt;, oferece um excelente meio de manipular essas imagens, e o método &lt;code&gt;BitBlit&lt;/code&gt; da API do Windows, nos fornece um modo rápido de copiar imagens para o frame buffer.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Um Pouco de Código (finalmente)&lt;/h3&gt;&lt;p&gt;Para melhorar um pouco a organização do código escrito no post anterior, vamos criar uma interface &lt;code&gt;IDrawable&lt;/code&gt; e fazer com que nosso objeto &lt;code&gt;TBackground&lt;/code&gt; a implemente.&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;IDrawable = interface&lt;br /&gt;  ['{3E41F055-58F6-4990-9C94-AA29FD4D7CF4}']&lt;br /&gt;  function GetVisible: boolean;&lt;br /&gt;  function GetRect : TRect;&lt;br /&gt;&lt;br /&gt;  procedure SetVisible(const Value: boolean);&lt;br /&gt;  procedure Draw(Canvas:TCanvas);&lt;br /&gt;&lt;br /&gt;  property Rect: TRect read GetRect;&lt;br /&gt;  property Visible: boolean read GetVisible write SetVisible;&lt;br /&gt;end;&lt;/pre&gt;&lt;p&gt;A interface é bem intuitiva e dispensa maiores explicações. Ela irá definir o “contrato” para todos os objetos renderizáveis no nosso programa. Agora segue nova definição de &lt;code&gt;TBackground&lt;/code&gt; adaptado para implementar &lt;code&gt;IDrawable&lt;/code&gt;.&lt;br /&gt;&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;TBackgroung = class(TInterfacedObject, IDrawable)&lt;br /&gt;private&lt;br /&gt;  fStep: byte;&lt;br /&gt;  fSize: uCommon.TSize;&lt;br /&gt;  fVisible: boolean;&lt;br /&gt;  function GetVisible: boolean;&lt;br /&gt;  function GetRect : TRect;&lt;br /&gt;  procedure SetVisible(const Value: boolean);&lt;br /&gt;public&lt;br /&gt;  constructor Create(pWidth: integer=640; pHeight:integer=480);&lt;br /&gt;  destructor Free;&lt;br /&gt;published&lt;br /&gt;  {IDrawable}&lt;br /&gt;  property Rect: TRect read GetRect;&lt;br /&gt;  property Visible: boolean read GetVisible write SetVisible;&lt;br /&gt;&lt;br /&gt;  {TBackgroung}&lt;br /&gt;  property Size : uCommon.TSize read fSize;&lt;br /&gt;  property Step : byte read fStep write fStep;&lt;br /&gt;end;&lt;/pre&gt;Além das propriedades e métodos da interface, criamos duas outras, &lt;code&gt;Size&lt;/code&gt; e &lt;code&gt;Step&lt;/code&gt;, que irão nos auxiliar no controle da renderização e no controle da animação. Vamos criar uma série de quadros vermelhos que irão mudar de cor de acordo com o valor da propriedade Step. Para isto, vamos implementar o método &lt;code&gt;Draw&lt;/code&gt;.&lt;br /&gt;&lt;pre name="code" class="delphi"&gt;procedure TBackgroung.Draw(Canvas: TCanvas);&lt;br /&gt;const&lt;br /&gt;  SquareW    = 40; {largura de cada bloco}&lt;br /&gt;  SquareH    = 40; {altura de cada bloco}&lt;br /&gt;  SquaresC   = 640 div SquareW + 1; {colunas}&lt;br /&gt;  SquaresR   = 480 div SquareH + 1; {linhas}&lt;br /&gt;var&lt;br /&gt;  col, row, i : integer;&lt;br /&gt;  r : TRect;&lt;br /&gt;begin&lt;br /&gt;  if fVisible then begin&lt;br /&gt;  for col:=0 to SquaresC-1 do&lt;br /&gt;      for row :=0 to SquaresR-1 do begin&lt;br /&gt;          r.Left   := Col * SquareW;&lt;br /&gt;          r.Top    := Row * SquareH;&lt;br /&gt;          r.Right  := r.Left + SquareW;&lt;br /&gt;          r.Bottom := r.Top + SquareH;&lt;br /&gt;&lt;br /&gt;          Canvas.Brush.Color := col * row + Step;&lt;br /&gt;         Canvas.FillRect(r);&lt;br /&gt;      end;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;/pre&gt;&lt;p&gt;O que fazemos aqui é dividir a tela em linhas e colunas de acordo com as contantes &lt;code&gt;SquareW&lt;/code&gt; (a largura de cada quadrado) e &lt;code&gt;SquareH&lt;/code&gt; (altura de cada quadrado), atribuir a cada um destas “células” uma cor diferente, que calculamos com base na linha, na coluna e no valor da propriedade &lt;code&gt;Step&lt;/code&gt; para finalmente, desenharmos uma a uma as “células” no Canvas.&lt;/p&gt;&lt;p&gt;Só nos resta agora “animar” a cena alterando a propriedade &lt;code&gt;Step&lt;/code&gt; após cada renderização. Faremos isto no nosso loop principal através do método &lt;code&gt;UpdateAnimation&lt;/code&gt;.&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;procedure TForm1.OnIdle(Sender: TObject; var Done: Boolean);&lt;br /&gt;begin&lt;br /&gt;  ProcessInput;&lt;br /&gt;  UpdateAnimation;&lt;br /&gt;  DrawToBuffer;&lt;br /&gt;  Blit;&lt;br /&gt;  Done := False;&lt;br /&gt;end;&lt;/pre&gt;&lt;p&gt;E agora, a implementação de UpdateAnimation.&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;procedure TForm1.UpdateAnimation;&lt;br /&gt;begin&lt;br /&gt;  BackGnd.Step := BackGnd.Step + 1;&lt;br /&gt;end;&lt;/pre&gt;&lt;p&gt;Pronto! Nosso background animado está concluído. Execute o código para ver o padrão vermelho mudando de tom e experimente brincar com as constantes do método Draw para chegar a outros resultados. Observe que a classe &lt;code&gt;TBall&lt;/code&gt; também foi alterada para implementar a interface &lt;code&gt;IDrawable&lt;/code&gt; e que uma outra interface (&lt;code&gt;IMoveable&lt;/code&gt;) foi criada para definir os objetos capazes de se mover pela tela.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Downloads&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.fabianosalles.eti.br/blog/delphi/files/animacoes/AnimVCLIII-fontes.zip"&gt;Código Fonte&lt;/a&gt; | &lt;a href="http://www.fabianosalles.eti.br/blog/delphi/files/animacoes/AnimVCLIII-exe.zip"&gt;Executável&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1115864231576611699-3871701258502540248?l=delphigames.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphigames.blogspot.com/feeds/3871701258502540248/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1115864231576611699&amp;postID=3871701258502540248' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/3871701258502540248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/3871701258502540248'/><link rel='alternate' type='text/html' href='http://delphigames.blogspot.com/2009/07/animacoes-em-tempo-real-com-vcl-parte.html' title='Animações em tempo real com a VCL - Parte III'/><author><name>Fabiano Salles</name><uri>http://www.blogger.com/profile/06349830371007868936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_TMF2yTWTSl0/SGOIwxW72LI/AAAAAAAAADs/_1RXXbnFwwg/S220/fabiano-01.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_TMF2yTWTSl0/Sms5KnQE7KI/AAAAAAAAAHA/HH3bcJh8hBo/s72-c/01.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1115864231576611699.post-4494331927545147796</id><published>2008-12-10T19:49:00.025-02:00</published><updated>2009-07-25T15:33:29.069-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='animação'/><category scheme='http://www.blogger.com/atom/ns#' term='computação gráfica'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>Animações em tempo real com a VCL - Parte II</title><content type='html'>&lt;blockquote&gt;No post anterior, fizemos uma introdução ao conceito de “Double buffer” e realizamos o tratamento da mensagem WM_ERASEBKGND para ajudar a otimizar um formulário VCL com o intuito de exibir animações de qualidade nele. Neste post, iremos finalizar estas otimizações.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Usando o evento OnIdle&lt;/h3&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_TMF2yTWTSl0/SUA__ppU1cI/AAAAAAAAAGY/3YKOb0_VvEA/s1600-h/VCLII.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 200px; height: 156px;" src="http://1.bp.blogspot.com/_TMF2yTWTSl0/SUA__ppU1cI/AAAAAAAAAGY/3YKOb0_VvEA/s200/VCLII.jpg" alt="" id="BLOGGER_PHOTO_ID_5278289126021715394" border="0" /&gt;&lt;/a&gt;O objeto &lt;code&gt;Application&lt;/code&gt; está presente em todos os programas GUI do Delphi e é utilizado para simplificar a interação com a &lt;code&gt;API&lt;/code&gt; do Windows. De fato, o objeto &lt;code&gt;Application&lt;/code&gt; encapsula todas as chamadas à &lt;code&gt;API&lt;/code&gt; necessárias para inicializar, registrar e manipular janelas, além de publicar alguns eventos globais.&lt;br /&gt;&lt;p&gt;O evento &lt;code&gt;TApplication.OnIdle&lt;/code&gt; é um desses eventos. Ele é disparado sempre que o programa fica ocioso, ou seja, sempre que não houver mais nenhuma instrução a ser executada, o evento &lt;code&gt;OnIdle&lt;/code&gt; será chamado. Isso o torna especialmente útil quando queremos realizar uma tarefa em segundo plano sem utilizar threads, ou quando queremos que uma determinada função seja executada repetidamente sem afetar o desempenho do programa.&lt;/p&gt;&lt;p&gt;Dois passos são necessários para utilizarmos o evento &lt;code&gt;OnIdle&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Primeiro declare um procedimento privado em seu formulário e implemente-o como o código a seguir:&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;procedure OnIdle(Sender: TObject; var Done: Boolean);&lt;br /&gt;begin&lt;br /&gt; Done := false;&lt;br /&gt;end;&lt;/pre&gt;&lt;p&gt;Note que não importa o nome do que você der ao método. O que importa é que a lista de parâmetros seja idêntica à do exemplo para que a assinatura do método seja compatível com a definição do evento &lt;code&gt;Application.OnIdle&lt;/code&gt; para que, dessa forma, possamos associar nosso método ao evento.&lt;/p&gt;&lt;p&gt;Para finalizar, ponha o trecho de código abaixo no &lt;code&gt;OnCreate&lt;/code&gt; do formulário e estaremos prontos para realizar nosso processamento neste evento.&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;procedure TfrmCGScreen.FormCreate(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt; Application.OnIdle := OnIdle;&lt;br /&gt;end;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;O loop principal (main loop)&lt;/h3&gt;&lt;p&gt;Iremos utilizar o &lt;code&gt;OnIdle&lt;/code&gt; para nosso loop principal.&lt;/p&gt;&lt;p&gt;O loop principal de uma aplicação de computação gráfica pode assumir várias formas, mas todas elas implementam variações da mesma lógica:&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;&lt;br /&gt;1. INICIO&lt;br /&gt;2. ENQUANTO(ESTADO  &lt;&gt;  SAIR)&lt;br /&gt;  2.1. PROCESSA OS COMANDOS DO USUÁRIO;&lt;br /&gt;  2.2. ATUALIZA DO ESTADO DA ANIMAÇÃO;&lt;br /&gt;  2.3. DESENHA A CENA NO BUFFER;&lt;br /&gt;  2.4. EXIBE A CENA NO MONITOR;&lt;br /&gt;3. FIM;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Vamos criar então os métodos equivalentes. Declare na seção privada do formulário os métodos a seguir e pressione &lt;code&gt;Ctl + Shit + C&lt;code&gt; para que o Delphi crie a implementação de todos:&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;procedure ProcessInput;    {passo 2.1}&lt;br /&gt;procedure UpdateAnimation; {passo 2.2}&lt;br /&gt;procedure DrawToBuffer;    {2.3}&lt;br /&gt;procedure Blit;            {2.4}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Agora implemente o método &lt;code&gt;OnIdle&lt;/code&gt; para que a estrutura do nosso algoritmo fique completa.&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;procedure TForm1.OnIdle(Sender: TObject; var Done: Boolean);&lt;br /&gt;begin&lt;br /&gt; ProcessInput;&lt;br /&gt; UpdateAnimation;&lt;br /&gt; DrawToBuffer;&lt;br /&gt; Blit;&lt;br /&gt;end;&lt;/pre&gt;&lt;p&gt;Se você compilar e executar o programa agora, você verá uma janela do Windows vazia. Nada muito empolgante até agora: temos a estrutura geral pronta, mas nada pra exibir.&lt;/p&gt;&lt;p&gt;Vamos criar um objeto to &lt;code&gt;TBall&lt;/code&gt; (adicione o arquivo uBall.pas ao seu projeto) no centro da tela. Declare uma variável pública chamada &lt;code&gt;Ball&lt;/code&gt; e modifique o evento &lt;code&gt;OnCreate&lt;/code&gt; do formulário para:&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;procedure TForm1.FormCreate(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt; ReportMemoryLeaksOnShutdown := True;&lt;br /&gt;&lt;br /&gt; {teremos uma tela de 800 x 600 pixels}&lt;br /&gt; ClientWidth := 800;              &lt;br /&gt; ClientHeight := 600;&lt;br /&gt;&lt;br /&gt; {Criamos nosso bitmap de buffer}&lt;br /&gt; fOffScreen := TBitmap.Create; &lt;br /&gt;&lt;br /&gt; {iremos trabalhar com cores de 24bit}&lt;br /&gt; fOffScreen.PixelFormat := pf24bit;&lt;br /&gt;&lt;br /&gt; {configura as dimensões do buffer de acordo com as dimensões do formulário}&lt;br /&gt; fOffScreen.Width := ClientWidth;&lt;br /&gt; fOffScreen.Height := ClientHeight;&lt;br /&gt; Ball := TBall.Create;&lt;br /&gt; Ball.Position:= Point(ClientWidth div 2, ClientHeight div 2);&lt;br /&gt; Ball.Color := clWhite;&lt;br /&gt; Ball.Diameter := 30;&lt;br /&gt; Application.OnIdle := OnIdle;&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Agora é preciso exibir o objeto. Vamos implementar os métodos &lt;code&gt;DrawToBuffer&lt;/code&gt; e &lt;code&gt;Blit&lt;/code&gt;:&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;procedure TForm1.DrawToBuffer;&lt;br /&gt;var&lt;br /&gt; Canvas : TCanvas;&lt;br /&gt;begin&lt;br /&gt; Canvas := fOffScreen.Canvas;&lt;br /&gt;&lt;br /&gt; {Primeiro, limpamos o buffer com um fundo preto...}&lt;br /&gt; Canvas.Brush.Color := clBlack;&lt;br /&gt;&lt;br /&gt; {Agora desenhamos a bola}&lt;br /&gt; Canvas.FillRect(fOffScreen.Canvas.ClipRect);&lt;br /&gt; Ball.Draw(Canvas);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TForm1.Blit;&lt;br /&gt;begin&lt;br /&gt; BitBlt(Canvas.Handle, 0, 0, ClientWidth, ClientHeight,&lt;br /&gt;        fOffScreen.Canvas.Handle, 0, 0, SRCCOPY);&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Com isto temos, finalmente, nosso framework funcionando. Tudo bem que ele não faz mais nada além de desenhar uma bola no meio da tela, mas o “trabalho sujo” de configuração do ambiente foi realizado.&lt;/p&gt;&lt;p&gt;Para finalizar este post, vamos movimentar um pouco a bola pela tela usando as setas do teclado. Implemente o método &lt;code&gt;ProccessInput&lt;/code&gt; usando a função &lt;code&gt;GetKeyState&lt;/code&gt; como na listagem abaixo. Note que os botões + e - irão manipular a velocidade em que a bola se movimenta.&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;procedure TForm1.ProcessInput;&lt;br /&gt;begin&lt;br /&gt; if GetKeyState(VK_UP) then&lt;br /&gt;    Ball.Move(0,-1);&lt;br /&gt;&lt;br /&gt; if GetKeyState(VK_DOWN) then&lt;br /&gt;    Ball.Move(0, 1);&lt;br /&gt;&lt;br /&gt; if GetKeyState(VK_LEFT) then&lt;br /&gt;    Ball.Move(-1, 0);&lt;br /&gt;&lt;br /&gt; if GetKeyState(VK_RIGHT) then&lt;br /&gt;    Ball.Move(1, 0);&lt;br /&gt;&lt;br /&gt; if GetKeyState(VK_SUBTRACT) then&lt;br /&gt;    Ball.Speed := Ball.Speed - 0.1;&lt;br /&gt;&lt;br /&gt; if GetKeyState(VK_ADD) then&lt;br /&gt;    Ball.Speed := Ball.Speed + 0.1;&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Compile o projeto e experimente um pouco. Note que a bola não ultrapassa os limites da tela e que a classe &lt;code&gt;TBall&lt;/code&gt; é responsável por este tratamento.&lt;/p&gt;&lt;p&gt;No próximo post, iremos adicionar um fundo com animação iremos expandir a classe &lt;code&gt;TBall&lt;/code&gt; para trabalhar com sprites animados.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Até o próximo post.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;h3&gt;Downloads&lt;br /&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://fabianosalles.eti.br/blog/delphi/files/animacoes/AnimVCLII-fonte.zip"&gt;Código fonte&lt;/a&gt; | &lt;a href="http://fabianosalles.eti.br/blog/delphi/files/animacoes/AnimVCLII-bin.zip"&gt;Executável&lt;/a&gt;&lt;/li&gt;&lt;ul&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1115864231576611699-4494331927545147796?l=delphigames.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphigames.blogspot.com/feeds/4494331927545147796/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1115864231576611699&amp;postID=4494331927545147796' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/4494331927545147796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/4494331927545147796'/><link rel='alternate' type='text/html' href='http://delphigames.blogspot.com/2008/12/animaes-em-tempo-real-com-vcl-parte-ii.html' title='Animações em tempo real com a VCL - Parte II'/><author><name>Fabiano Salles</name><uri>http://www.blogger.com/profile/06349830371007868936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_TMF2yTWTSl0/SGOIwxW72LI/AAAAAAAAADs/_1RXXbnFwwg/S220/fabiano-01.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_TMF2yTWTSl0/SUA__ppU1cI/AAAAAAAAAGY/3YKOb0_VvEA/s72-c/VCLII.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1115864231576611699.post-3205428891342979778</id><published>2008-09-18T17:13:00.022-03:00</published><updated>2009-07-25T15:51:00.094-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='animação'/><category scheme='http://www.blogger.com/atom/ns#' term='computação gráfica'/><title type='text'>Animações em tempo real com a VCL - Parte I</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_TMF2yTWTSl0/SNjo8HU7X2I/AAAAAAAAAEY/0rOePeLItx4/s1600-h/snapshot02.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://2.bp.blogspot.com/_TMF2yTWTSl0/SNjo8HU7X2I/AAAAAAAAAEY/0rOePeLItx4/s200/snapshot02.png" alt="" id="BLOGGER_PHOTO_ID_5249201485156933474" border="0" /&gt;&lt;/a&gt;O Delphi facilita muito a construção de interfaces gráficas. Arrastando componentes da barra de ferramentas e alterando suas propriedades pelo “object inspector”, é muito fácil construir uma interface consistente para a maioria das aplicações. Esta abordagem, porém, não pode ser utilizada para construir uma superfície de desenho adequada para a exibição de animações que exijam uma taxa de atualização aceitável (pelo menos 20 quadros por segundo). Para isso, a solução mais óbvia seria utilizar uma &lt;a href="http://pt.wikipedia.org/wiki/API"&gt;API &lt;/a&gt;ou &lt;a href="http://pt.wikipedia.org/wiki/Framework"&gt;framework &lt;/a&gt;projetado especificamente para este fim (como &lt;a href="http://www.opengl.org/"&gt;OpenGL &lt;/a&gt;ou &lt;a href="http://www.microsoft.com/games/en-US/aboutgfw/Pages/directx10.aspx"&gt;DirectX&lt;/a&gt;). Existem, porém, dois problemas a serem vencidos para adotar um framework destes. O primeiro problema é que, caso não haja um hardware gráfico moderno disponível na máquina onde a aplicação irá ser executada, nenhuma aceleração de será provida (leia-se: todo o processamento gráfico será feito por software). O segundo problema é a curva de aprendizado, consideravelmente longa, que o programador terá de vencer para conseguir aproveitar os recursos que elas possam oferecer.&lt;br /&gt;&lt;p&gt;Então, qual biblioteca utilizar? Não dá pra fazer isso com a própria VCL?&lt;/p&gt;&lt;p&gt;Sim. Dá sim. Mas algumas otimizações precisam ser feitas. E é sobre estas otimizações que vamos falar.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Double Buffer ou Backbuffer&lt;/h3&gt;&lt;p&gt;O &lt;code&gt;TCanvas&lt;/code&gt; representa uma superfície de desenho que pode ser entendida e tratada como um array de pixels ou um buffer de pixels. O Windows mapeia este buffer para a memória de vídeo e então a placa de vídeo trata de interpretar esta informação e convertê-la em uma imagem visível no monitor.&lt;/p&gt;&lt;p&gt;Se desenharmos direto num &lt;code&gt;TCanvas&lt;/code&gt; de um objeto visível, o desenho será imediatamente atualizado na tela. Até aí, tudo bem. Desde que sejam desenhados um ou dois objetos por vez, tudo irá ser atualizado rápido o suficiente para que a transição não seja facilmente percebida.&lt;/p&gt;&lt;p&gt;Ponha um &lt;code&gt;TTimer&lt;/code&gt; num form, configure a propriedade &lt;code&gt;interval&lt;/code&gt; para 20, carregue uma imagem qualquer num &lt;code&gt;TImage&lt;/code&gt; e ponha o seguinte código no evento &lt;code&gt;OnTimer&lt;/code&gt;:&lt;br /&gt;&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;procedure TForm1.Timer1Timer(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;  Canvas.Brush.Color := clWhite;&lt;br /&gt;  Canvas.FillRect(Canvas.ClipRect);&lt;br /&gt;  Canvas.Draw(X, Y, Image1.Picture.Graphic);&lt;br /&gt;  Inc(X);&lt;br /&gt;  Inc(Y);&lt;br /&gt;  if X &gt;= ClientWidth - Image1.Width then&lt;br /&gt;     X := 0;&lt;br /&gt;  if Y &gt;= ClientHeight - Image1.Height then&lt;br /&gt;     Y := 0;&lt;br /&gt;end;&lt;/pre&gt;&lt;p&gt;Ao executar &lt;a href="http://fabianosalles.eti.br/blog/delphi/files/animacoes/AnimSemBuffer-exe.zip"&gt;este programa&lt;/a&gt;, você verá sua imagem sendo redesenha aproximadamente 50 vezes por segundo (1000/20=50), o suficiente para causar a impressão de movimento, mas a imagem fica piscando constantemente e o resultado é realmente muito feio.&lt;/p&gt;&lt;p&gt;A idéia geral do buffer duplo (Double buffer) é ter uma segunda área de desenho que fique sempre invisível. Daí, em vez de desenhar direto na tela, todos os desenhos seriam gerados neste buffer e, somente depois de pronto, copiaríamos o desenho para a área visível da tela, numa única operação.&lt;/p&gt;&lt;p&gt;A primeira impressão que essa idéia passa é de que, como estaremos percorrendo um caminho maior, as coisas ficarão mais lentas. Mas o fato é que, quando desenhamos num &lt;code&gt;TCanvas&lt;/code&gt; visível, a operação demora mais porque, além do tempo gasto com o desenho em si, o programa tem que esperar a memória de vídeo ser atualizada para que o as mudanças apareçam na tela e o programa possa seguir. Quando desenhamos na memória (num &lt;code&gt;TCanvas&lt;/code&gt; não visível) este atraso não existe, logo, a operação é concluída muito mais rápido. Além disso, quando vamos exibir a imagem na tela, ela já está pronta e somente uma operação de desenho será realizada nesta “área lenta”, o que contribui para que a animação tenha uma aparência mais agradável.&lt;/p&gt;&lt;p&gt;Vejamos como implementar esta idéia em Delphi.&lt;/p&gt;&lt;p&gt;Primeiro, declare uma variável privada do tipo &lt;code&gt;TBitmap&lt;/code&gt; para ser o nosso “back buffer” e trate a inicialização e destruição deste objeto:&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;private&lt;br /&gt;  { Private declarations }&lt;br /&gt;  fOffScreen: TBitmap;&lt;br /&gt;&lt;br /&gt;(...)&lt;br /&gt;&lt;br /&gt;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);&lt;br /&gt;begin&lt;br /&gt;  FreeAndNil(fOffScreen);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;(...)&lt;br /&gt;&lt;br /&gt;procedure TForm1.FormCreate(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;  X := 0;&lt;br /&gt;  Y := 0;&lt;br /&gt;  fOffScreen := TBitmap.Create;&lt;br /&gt;  fOffScreen.PixelFormat := pf24bit;&lt;br /&gt;  fOffScreen.Width := ClientWidth;&lt;br /&gt;  fOffScreen.Height := ClientHeight;&lt;br /&gt;end;&lt;/pre&gt;&lt;p&gt;Agora vamos desenhar na memória e, quando concluído o desenho, vamos transferi-lo para a “área visível” da tela.&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;procedure TForm1.Timer1Timer(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;  fOffScreen.Canvas.Brush.Color := clWhite;&lt;br /&gt;  fOffScreen.Canvas.FillRect(fOffScreen.Canvas.ClipRect);&lt;br /&gt;  fOffScreen.Canvas.Draw(X, Y, Image1.Picture.Graphic);&lt;br /&gt;&lt;br /&gt;  BitBlt(Canvas.Handle, 0, 0,&lt;br /&gt;         ClientWidth,&lt;br /&gt;         ClientHeight,&lt;br /&gt;         fOffScreen.Canvas.Handle,&lt;br /&gt;         0, 0, SRCCOPY);&lt;br /&gt;  Inc(X);&lt;br /&gt;  Inc(Y);&lt;br /&gt;  if X &gt;= ClientWidth - Image1.Width then&lt;br /&gt;     X := 0;&lt;br /&gt;  if Y &gt;= ClientHeight - Image1.Height then&lt;br /&gt;     Y := 0;&lt;br /&gt;end;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Execute &lt;a href="http://fabianosalles.eti.br/blog/delphi/files/animacoes/AnimDoubleBuffer-exe.zip"&gt;este programa&lt;/a&gt; e veja que o problema da imagem piscando (conhecido como flickering) foi resolvido.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Eliminando interferências do Windows&lt;/h3&gt;&lt;p&gt;Outra otimização mais sutil, mas não menos importante, é o tratamento adequado da mensagem &lt;code&gt;WM_ERASEBKGND&lt;/code&gt; que o Windows envia ao programa quando ele acha que alguma área da janela deve ser atualizada.&lt;br /&gt;O Delphi, por padrão, em resposta a esta mensagem irá invalidar toda a área cliente da janela, forçando um redesenho completo. Este comportamento faz sentido quando deixamos que o Delphi cuide sozinho do desenho e da atualização da janela, mas no nosso caso, queremos ter controle completo sobre o modo que a janela será exibida.&lt;/p&gt;&lt;p&gt;Vamos criar uma procedure que irá realizar o tratamento desta mensagem. Declare o seguinte procedimento :&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;procedure WMEraseBg(var Msg: TWMEraseBkgnd); message WM_ERASEBKGND;&lt;/pre&gt;&lt;p&gt;E em sua implementação diga ao Windows, que você mesmo irá tratar do redesenho da janela, setando a mensagem &lt;code&gt;MSG&lt;/code&gt; para 0:&lt;/p&gt;&lt;pre name="code" class="delphi"&gt;procedure TfrmCGScreen.WMEraseBg(var Msg: TWMEraseBkgnd);&lt;br /&gt;begin&lt;br /&gt;  Msg.Result := 0;&lt;br /&gt;end;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Um template para animações&lt;/h3&gt;&lt;p&gt;Com estas duas otimizações implementadas, já dá pra fazer pequenas animações executarem de maneira eficiente. Mas ainda há espaço para outras otimizações (que trataremos no próximo post), como executar o programa em full screen, substituir o &lt;code&gt;TTimer&lt;/code&gt; por funções mais precisas como &lt;code&gt;QueryPerformaceCounter&lt;/code&gt; e utilizar o evento &lt;code&gt;OnIdle&lt;/code&gt; do &lt;code&gt;TApplication&lt;/code&gt; para realizar os desenhos da animação.&lt;/p&gt;&lt;p&gt;Neste &lt;a href="http://fabianosalles.eti.br/blog/delphi/files/templates/CGFormTemplate-src.zip"&gt;link&lt;/a&gt;, você pode baixar os fontes de um projeto que implementa todas estas otimizações e utilizá-lo como template para seus próprios projetos. Faça o download do arquivo, abra-o no Delphi, clique com um botão direito em cima do form e escolha a opção “Add to Repository”. Pronto. Este template estará  disponível no “Object Repository”!&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Para usar o template, clique no menu &lt;code&gt;File &gt; New &gt; Other,&lt;/code&gt; escolha o formulário adicionado anteriormente, marque a opção “inherit” e sobrescreva o método &lt;code&gt;DrawScene&lt;/code&gt; para criar suas animações.&lt;/p&gt;&lt;p&gt;Até o próximo post.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Downloads&lt;br /&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Animação sem buffer: &lt;a href="http://fabianosalles.eti.br/blog/delphi/files/animacoes/AnimacaoSemDoubleBuffer-src.zip"&gt;Código fonte&lt;/a&gt; | &lt;a href="http://fabianosalles.eti.br/blog/delphi/files/animacoes/AnimSemBuffer-exe.zip"&gt;executável&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Animação com buffer: &lt;a href="http://fabianosalles.eti.br/blog/delphi/files/animacoes/AnimacaoComDoubleBuffer-src.zip"&gt;Código fonte&lt;/a&gt; | &lt;a href="http://fabianosalles.eti.br/blog/delphi/files/animacoes/AnimDoubleBuffer-exe.zip"&gt;executável&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Template com otimizações: &lt;a href="http://fabianosalles.eti.br/blog/delphi/files/templates/CGFormTemplate-src.zip"&gt;Código fonte&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1115864231576611699-3205428891342979778?l=delphigames.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphigames.blogspot.com/feeds/3205428891342979778/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1115864231576611699&amp;postID=3205428891342979778' title='3 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/3205428891342979778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/3205428891342979778'/><link rel='alternate' type='text/html' href='http://delphigames.blogspot.com/2008/09/animaes-com-vcl.html' title='Animações em tempo real com a VCL - Parte I'/><author><name>Fabiano Salles</name><uri>http://www.blogger.com/profile/06349830371007868936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_TMF2yTWTSl0/SGOIwxW72LI/AAAAAAAAADs/_1RXXbnFwwg/S220/fabiano-01.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_TMF2yTWTSl0/SNjo8HU7X2I/AAAAAAAAAEY/0rOePeLItx4/s72-c/snapshot02.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1115864231576611699.post-8044737993172242499</id><published>2008-08-21T19:50:00.008-03:00</published><updated>2008-08-21T20:45:09.181-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='sistema de partículas'/><category scheme='http://www.blogger.com/atom/ns#' term='partículas'/><category scheme='http://www.blogger.com/atom/ns#' term='computação gráfica'/><title type='text'>Sistemas de partículas</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_TMF2yTWTSl0/SK3yFRMuH5I/AAAAAAAAAEI/p739--ImNRA/s1600-h/particulas.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://3.bp.blogspot.com/_TMF2yTWTSl0/SK3yFRMuH5I/AAAAAAAAAEI/p739--ImNRA/s200/particulas.jpg" alt="" id="BLOGGER_PHOTO_ID_5237108114031779730" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;Segundo a dinâmica das partículas, um sistema de partículas é o conjunto de leis físicas que regem um conjunto de &lt;/span&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;n&lt;/span&gt;&lt;span style="font-size:85%;"&gt; partículas partindo de um centro de massa ou emissor. Muitos fenômenos podem ser modelados como sistemas de partículas. A chuva (cada gota é uma partícula e o emissor é o conjunto de nuvens de onde as gotas vêm), a neve (cada floco uma partícula e o emissor, o ponto de condensação/cristalização do vapor de água) o fogo (cada chama é uma partícula e o emissor é o material sendo queimado), todos estes podem ser descritos como tal.&lt;br /&gt;&lt;br /&gt;Um sistema simples utilizando vetores bidimensionais para calcular a o deslocamento das partículas pode ser facilmente modelado no Delphi e exibido num TCanvas padrão.  Neste sistema (veja os links abaixo) é possível manipular a força do vento, a força da gravidade e o centro de massa de maneira  interativa e ver em tempo real o resultado na tela.&lt;br /&gt;Este sistema de exemplo se distancia da realidade física por não calcular desvios de rota resultantes de colisões entre partículas e implementar somente duas grandezas vetoriais (a gravidade e o vento) quando no mundo real o número de grandezas envolvidas num sistema de partículas é muito maior. Além disso, cada partícula percorre uma trajetória linear, o que nem sempre é condizente com o sistema que se está tentando simular.&lt;br /&gt;&lt;br /&gt;Mesmo com todas essas omissões, é possível conseguir efeitos especiais atraentes e leves para serem usados em jogos. Este exemplo faz uso das rotinas gráficas da API do Windows, portanto, não requer nenhum componente ou biblioteca especial para compliar.&lt;br /&gt;&lt;br /&gt;Para controlar a gravidade, utilize as teclas "+" e "-" do teclado numérico. Para controlar a direção e a força do vento, use as setas direcionais.&lt;br /&gt;&lt;br /&gt;Evoé...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://fabianosalles.eti.br/blog/delphi/files/particulas/particulas-src.zip"&gt;Código fonte&lt;/a&gt;&lt;br /&gt;&lt;a href="http://fabianosalles.eti.br/blog/delphi/files/particulas/particulas-exe.zip"&gt;Executável&lt;/a&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1115864231576611699-8044737993172242499?l=delphigames.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphigames.blogspot.com/feeds/8044737993172242499/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1115864231576611699&amp;postID=8044737993172242499' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/8044737993172242499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/8044737993172242499'/><link rel='alternate' type='text/html' href='http://delphigames.blogspot.com/2008/08/sistema-de-partculas.html' title='Sistemas de partículas'/><author><name>Fabiano Salles</name><uri>http://www.blogger.com/profile/06349830371007868936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_TMF2yTWTSl0/SGOIwxW72LI/AAAAAAAAADs/_1RXXbnFwwg/S220/fabiano-01.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_TMF2yTWTSl0/SK3yFRMuH5I/AAAAAAAAAEI/p739--ImNRA/s72-c/particulas.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1115864231576611699.post-196353252259552803</id><published>2008-08-20T17:50:00.005-03:00</published><updated>2008-08-20T18:37:32.304-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='campo minado'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>YASM, Um Clone do Clássico Campo Minado</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_TMF2yTWTSl0/SKyF2owKUrI/AAAAAAAAAEA/FGau41iXdZs/s1600-h/yasm-shot01.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://3.bp.blogspot.com/_TMF2yTWTSl0/SKyF2owKUrI/AAAAAAAAAEA/FGau41iXdZs/s200/yasm-shot01.png" alt="" id="BLOGGER_PHOTO_ID_5236707640423895730" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;YASM&lt;/span&gt;&lt;span style="font-size:85%;"&gt;, sigla para &lt;span style="font-weight: bold;"&gt;Yet Another Mine Sweeper Clone&lt;/span&gt; ou, em português: Só Mais um Clone do Campo Minado, é um jogo que escrevi já há algum tempo para participar de uma competição de remakes de jogos clássicos que infelizmente acabou sendo cancelada.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Eu o escolhi para esta minha primeira postagem porque é um código simples e porque, como ele não utiliza nenhuma API ou componentes de terceiros, caso alguém queira estudar o código-fonte, basta fazer o download e abrir o projeto no Delphi. Além disso, depois que passei a utilizar o BDS2007, que utiliza o FASTMM por padrão como seu gerenciador de memória, fiquei curioso para ver o que o relatório de memory leaks ia acusar nos meus programas. Abri o projeto no Delphi 2007, habilitei a contagem de alocação e não deu outra: seis memory leaks detectados!&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Segue os links para o código fonte (já corrigido) e o arquivo executável.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Evoé...&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;a href="http://www.fabianosalles.eti.br/blog/delphi/files/yasm/yasm-src.zip"&gt;Código fonte&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.fabianosalles.eti.br/blog/delphi/files/yasm/yasm-exe.zip"&gt;Executável&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ps : para ver se sua aplicação possui memory leaks no Delphi2007, no evento OnCreate do seu form, adicione o código: ReportMemoryLeaksOnShutdown := true;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1115864231576611699-196353252259552803?l=delphigames.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://delphigames.blogspot.com/feeds/196353252259552803/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1115864231576611699&amp;postID=196353252259552803' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/196353252259552803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1115864231576611699/posts/default/196353252259552803'/><link rel='alternate' type='text/html' href='http://delphigames.blogspot.com/2008/08/yasm-um-clone-do-clssico-campo-minado.html' title='YASM, Um Clone do Clássico Campo Minado'/><author><name>Fabiano Salles</name><uri>http://www.blogger.com/profile/06349830371007868936</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://bp3.blogger.com/_TMF2yTWTSl0/SGOIwxW72LI/AAAAAAAAADs/_1RXXbnFwwg/S220/fabiano-01.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_TMF2yTWTSl0/SKyF2owKUrI/AAAAAAAAAEA/FGau41iXdZs/s72-c/yasm-shot01.png' height='72' width='72'/><thr:total>4</thr:total></entry></feed>
