Uma Introdução a Sistemas de Partículas

Um grande “boa noite” a todos!

Gostaria de pedir desculpas por meu atraso em postar aqui a minha contribuição: somos um grupo de poucos escritores, então, qualquer atraso de um de nós leva a grandes problemas na manutenção da atualização deste blog.

Hoje venho aqui trazer uma breve explanação sobre uma das coisas que estudei durante certo tempo com meu amigo Edmar Souza Jr. (the great SuperSayajin! ) e que me parece ser sempre um assunto bastante atualizado e capaz de oferecer muitos resultados: os sistemas de partículas.
Sistemas de partículas são sistemas criados para gerenciar a criação, movimentação (às vezes também a colisão) e destruição de pequenos elementos que podem compor um cenário do jogo. Você pode escrever sistemas de partículas para simular:
- Chuva;
- Neve;
- Furacões; (este aqui eu não consegui fazer… ainda! ;) )
- Espirais; (semelhante àquelas galáxias vistas nos filmes)
- Explosões;
- Fontes d’água;
- Fogo;
- E muuuuuuitas outras coisas!

Ou seja, um sistema de partículas pode tornar o seu jogo muito mais atraente, já que a posição e movimentação das partículas não é pré-programada (entretanto, quanto mais partículas a serem renderizadas, mais pesada fica a aplicação!).

Certo, certo… Já falamos sobre vantagens e cuidados, agora vamos ver como deve ser criado um sistema… O meu sistema eu criei da seguinte forma:
- A classe (sim, só gosto de trabalhar com orientação a objetos, nem me venham com história de programação estruturada! :D ) controladora do sistema, que mantém uma lista de todas as partículas e as funções para criar partículas, inicializá-las, movimentá-las e destruí-las;
- A classe a que deve pertencer cada partícula, armazenando nela somente informações da partícula especificamente, como: coordenadas retangulares ou polares no espaço (não sabe trabalhar com coordenadas polares? Então está na hora de aprender, pois eu precisei delas para fazer os espirais! ), tempo de vida, contador que auxilie a animação, etc.

Agora, lembre-se que forças externas podem interferir no movimento das partículas, forças como:
- Gravidade (influencia na posição vertical);
- Vento (influencia na posição horizontal);
- Campo elétrico;
- Campo magnético (provido ou não pelas outras partículas).

No meu sistema implementei levando em conta somente a gravidade e o vento.

Os segredos para se desenvolver um bom sistema são:
- Saber quais propriedades a serem atribuídas a uma partícula;
- Saber como inicializar corretamente (criar e posicionar uma partícula);
- Saber como deve ser feita a movimentação (não é muito difícil - estude exatamente como as coisas se comportam na vida real e aplique esses conceitos);
- Saber o momento para destruir uma partícula (geralmente as partículas são destruídas após um determinado tempo transcorrido, ao colidir com algo ou ao atingir determinada distância do ponto de criação).

Uma curiosidade: gotas de chuva caindo em sua simulação não devem possuir uma aceleração devido à gravidade! Isso é uma regra da Física - um corpo caindo chega a uma velocidade máxima e dela não ultrapassa, devido à resistência que o ar oferece e isso ocorre com as gotas de chuva. Os flocos de neve também não sofrem aceleração gravitacional, estes devido à sua aerodinâmica.

As partículas de explosão e da fonte d’água podem ser criadas da mesma forma: por meio de dispersão, ou seja, as partículas possuem uma velocidade inicial que as levam a se afastar de um ponto origem e pode-se aplicar ou não as leis da gravidade e do vento (é óbvio que a fonte sofre essa ação, não é?). Mais uma curiosidade: quando coloco um tempo de vida razoável nas partículas, uma potência (velocidade inicial com que se afastam as partículas) baixa, sem sofrer a ação da gravidade, tenho um efeito semelhante ao da chama de uma vela! :)

Bem, com isso que foi dito já há um pontapé inicial para compreendermos como os sistemas de partículas funcionam, não?

Seguindo estas orientações, vocês podem desenvolver quaisquer sistemas de partículas (é só colocar a cabeça para funcionar!).

 

Bem, agora vou mostrar aqui como criar um sistema de partículas que simule uma chuva em Delphi, ok?


Apresentarei aqui um sistema muito simplificado, não estarão envolvidos aqui tantos parâmetros quanto foram necessários no sistema que desenvolvi, mas já dará um resultado razoável em seus jogos.

Obs: No período em que estava estudando, desenvolvi cada tipo de sistema de partícula como um componente para o DelphiX e, posteriormente, comecei a converter todos os componentes de sistemas de partículas para classes e “encapsulei-as” em um componente principal chamado DXParticleSystemManager, mas infelizmente interrompi a conversão há algum tempo :( .


Como já disse, uma classe (ou tipo, que é o que vou usar agora) deve designar a construção das partículas:

   TGota = record
              x: integer;
              y: integer;
           end;

E uma outra classe (mais uma vez, vou preferir criar um tipo aqui, só para tornar o processo mais simples) para controlar tudo, ou seja, nosso sistema:

   TChuvaSprite = record
                     intensidade: integer;
                     gotas: TList;
                     vento: integer;
                     gravidade: integer;
                     superficie: TCanvas;
                  end;


Bem, defina também um método que inicialize o sistema (CriarChuva) e um método que, a cada vez que for chamado, ele irá desenhar sobre a superfície e recalcular a posição das partículas (MoveGotas).
Pronto! Agora vamos dizer mais ou menos o que deve ser feito na inicialização:



procedure CriarChuva;
var i: integer;
     pgota: ^TGota;
begin
   if intensidade > 0 then
      for i := 0 to intensidade - 1 do
         begin
            new(pgota);
            pgota.x := random(superficie.width);
            pgota.y := random(superficie.height);
            gotas.Add(pgota);
         end;
end;


E agora, vamos ver como deve ser feita a movimentação e desenho de cada ponto. Só lembrando: as partículas de chuva não sofrem aceleração gravitacional, entretanto, em nosso sistema, quanto maior a gravidade, maior a velocidade de queda vertical da gota (só que essa velocidade é constante!!!) e só para facilitar, as gotas de chuva terão a cor ClAqua…


procedure MoveGotas;
var i: integer;
      pgota: ^TGota;
begin
   superficie.Pen.Color := ClAqua;
   for i := 0 to gotas.Count - 1 do
   begin
       pgota := gotas.Items[i];
       superficie.MoveTo(pgota.x, pgota.y);
       superficie.LineTo(pgota.x + vento, pgota.y + gravidade);
       pgota.x := pgota.x + 2*vento;
       pgota.y := pgota.y + 2*gravidade;
       if pgota.x <> superficie.width then
           pgota.x := 0;
       if pgota.y <> superficie.height then
            pgota.y := 0;
   end;
   superficie.release;
end;

Certo, agora, alguns detalhes: se você colocar o código assim, desse jeito, pode dar algum problema na hora de redesenhar a superfície. Eu trabalho com os valores x e y como reais, mas daí tem que tomar cuidado nas validações e conversões, senão acaba ficando tudo uma porcaria e idem quanto a gravidade negativa, pode trabalhar com ela, mas talvez tenha que fazer ajustes no algoritmo, de acordo com componentes e bibliotecas que estiver usando.

Antes que me perguntem: e por que não já colocou um código perfeito para usarmos, sem falhas e com muitos efeitos?
Simples: meu objetivo aqui é MOSTRAR COMO FAZER e não só chegar e já passar o código-fonte, senão ninguém estaria aprendendo, não é? E já que o objetivo é aprender, temos que fazer restrições nas funcionalidades e tentarmos criar algo bem genérico e de baixa complexidade, como isto!

Em outro momento eu mostro algo aqui um pouco mais avançado, mas quem quiser implementar algo um pouco melhor, uma dica: mesmo em 2D, podemos inserir mais uma coordenada às gotas, uma coordenada z, que quanto maior esse z, mais próxima a gota está da tela, portanto maior ela ficaria, mais rápido ela cairia, ok?


Pronto, por enquanto é isso! Agora é com vocês: recriem o sistema de partículas para chuvas e implementem, por exemplo, o sistema para neve, pois é também simples, mas introduz uma nova característica: o movimento das partículas não é retilíneo, mas sim, algo similar a uma senóide. :)

Ah, para que eu não esqueça, estou subindo também o executável que implementei no período em questão, com vários sistemas de partículas diferentes.

Para baixar, é só clicar aqui: Uma Introdução a Sistemas de Partículas

Agora sim: até mais!

Leave a Reply