Pascal Gamer Magazine

Acaba de sair o segundo exemplar da revista eletrônica "Pascal Gamer Magazine".

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 Sulaco) e Christina Warne (administradora do Pascal Game Development).

Nesta edição, o foco da revista está voltado para o resultado do Concurso Anual de Jogos em Pascal, o PGD, um dos eventos mais significativo da modesta comunidade de desenvolvedores indie que utilizam o bom e velho pascal como linguagem.
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.

Quem quiser conferir, pode acessar e baixar gratuitamente o exemplar em http://pascalgamer.com/

Migração de Servidor Concluída

A migração dos arquivos para o novo servidor foi concluída!
Todos os links para código-fontes e executáveis já estão funcionando.

Evoé...

Migração de Servidor

Estou migrando os arquivos do blog para um novo servidor.
Caso algum link estaja quebrado, por favor, me avise em fabiano.salles@gmail.com que corrigirei o mais vreve possível.
Até este sábado, dia 10, a migração estará concluída.

Abraços.

Alguns Jogos criados em Delphi


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.
É 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!
Todos os jogos dos vídeos foram feitos por hobistas utilizando delphi e/ou free pascal. Alguém ainda duvida?

Animações em tempo real com a VCL - Parte IV

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.

Opacidade

Segundo o Wikipedia:
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. (http://pt.wikipedia.org/wiki/Opacidade)

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 256 valores possíveis (0..255) onde 0 define uma imagem completamente transparente e 255 uma imagem completamente opaca.
Vamos criar um descendente de TBitmap onde adicionaremos esta propriedade.


TSprite = class(TBitmap)
private
   fOpacity: byte;
   procedure SetOpacity(const Value: byte);
published
   property Opacity: byte read FOpacity write SetOpacity; 
end;

Agora vamos instanciar nosso sprite na inicialização do programa (lembrando que estamos modificando o código do template cirado nos artigos anteriores)

procedure TForm1.FormCreate(Sender: TObject);
begin
   ReportMemoryLeaksOnShutdown := True;
   ClientWidth   := 800;               
   ClientHeight  := 600;               
   fOffScreen := TBitmap.Create;       
   fOffScreen.PixelFormat := pf24bit;  
   fOffScreen.Width  := ClientWidth;   
   fOffScreen.Height := ClientHeight;  
   fOffScreen.Canvas.Font.Color := clGray;
   fOffScreen.Canvas.Font.Size  := 9;

   sprite := TSprite.Create;
   sprite.LoadFromFile('img01.bmp');
   sprite.Opacity := MAXBYTE div 2;
   Application.OnIdle := OnIdle;
end;


Windows.AlphaBlend


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 50% de opacidade sobre um background preto (note que já configuramos opacidade como MAXBYTE div 2).
A primeira coisa que precisamos para usar o Windows.AlphaBlend é configurar um registro do tipo TBlendFunction (Veja a descrição oficial deste struct no MSDN).

procedure TForm1.DrawToBuffer;
var
  Canvas : TCanvas;
  Blendf : TBlendFunction;
begin
  Canvas := fOffScreen.Canvas;
  Canvas.Brush.Color := clBlack;
  Canvas.FillRect(fOffScreen.Canvas.ClipRect);

  Blendf.BlendOp    := AC_SRC_OVER;
  Blendf.BlendFlags := 0;
  Blendf.SourceConstantAlpha := sprite.Opacity;
  Blendf.AlphaFormat := AC_SRC_OVER;
end;

O parâmetro BlendOp representa a opração de mesclagem a executar. Como queremos copiar nosso sprite “por cima” da imagem de fundo, setamos BlendOP com a constante AC_SRC_OVER.
O parâmatro BlendFlags deve ser sempre zero.
SourceConstantAlpha define um valor de transparência a ser aplicado na imagem de origem. Aqui, simplesmente passamos o valor da opacidade de nosso sprite.
Por fim, AlphaFormat deve ser AC_SRC_OVER 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 SourceConstantAlpha.
Pronto. Com nosso TBlendFunction configurado, podemos desenhar o sprite semi-transparente. Complemente o método DrawToBuffer conforme a listagem abaixo e execute o programa para ver o resultado.

procedure TForm1.DrawToBuffer;
var
   Canvas : TCanvas;
   Blendf : TBlendFunction;
begin
   Canvas := fOffScreen.Canvas;
   Canvas.Brush.Color := clBlack;
   Canvas.FillRect(fOffScreen.Canvas.ClipRect);

   Blendf.BlendOp    := AC_SRC_OVER;
   Blendf.BlendFlags := 0;
   Blendf.SourceConstantAlpha := sprite.Opacity;
   Blendf.AlphaFormat := AC_SRC_OVER;

   Windows.AlphaBlend(
      Canvas.Handle,  {manipulador da imagem de destino}
      fOffScreen.Width - sprite.Width, {coordenada X}
      0,                               {coordenada Y}
      sprite.Width,                    {largura da área de desenho}
      sprite.Height,                   {altura da área de desenho} 

      sprite.Canvas.Handle, {manipulador da imagem de origem}
      0,                    {coordenada X}
      0,                    {coordenada Y}
      sprite.Width,         {largura da imagem de origem}
      sprite.Height,        {altura da imagem de origem}

      Blendf                 {parâmetros de executação(TBlendFunction)}
   );

   Canvas.TextOut(10, 10, Format('Opacidade : %d', [sprite.Opacity]));
end;
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.


Fade In e Fade Out

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 Opacity ao longo do tempo. Vejamos como ficará o método UpdateAnimation.

procedure TForm1.UpdateAnimation;
begin
  if OpIncreasing then
     sprite.Opacity := sprite.Opacity + 1
  else
     sprite.Opacity := sprite.Opacity - 1;

  case sprite.Opacity of
    0   : OpIncreasing := true;
    255 : OpIncreasing := false;
  end;
end;

Execute o programa e veja os efeitos em funcionamento. Para conseguir novos efeitos, altere os valores dos incrementos e decrementos em cada iteração.
Até o próximo post.

Downloads

Links

Links para as postagens que fazem parte do mini curso "Animações em Tempo real com a VCL"