Tutorial 12 - Hello Effects

jMonkeyEngine 3 Tutorial (12) - Hello Effects

Anterior: Hello Audio, Próximo: Hello Physics

Quando você vê um dos seguintes em um jogo, então um sistema de partículas está provavelmente atrás disso:

  • Fogo, chamas, faíscas;
  • Chuva, neve, cascatas, folhas;
  • Explosões, detritos, ondas de choque;
  • Poeira, neblina, nuvens, fumaça;
  • Enxames de inseto, banhos de meteoro;
  • Feitiços mágicos.

Estes elementos de cena não podem ser modelados por malhas. Em termos muito simples:

  • A diferença entre uma explosão e uma nuvem de poeira é a velocidade do efeito de partícula.
  • A diferença entre chamas e uma cachoeira é a direção e a cor do efeito da partícula.

Efeitos de partícula podem ser animados (e.g. faíscas, quedas) e estáticos (cordões de grama, cabelo). Efeitos de não partícula incluem bloom/brilho, e motion blur/afterimage. Neste tutorial você aprende a como fazer partículas animadas (com.jme3.effect).

Para usar os ativos de exemplo em um novo projeto do SDK da jMonkeyEngine dê um clique com o botão direito em seu projeto, selecione "propriedades" ("Properties"), vá para "Bibliotecas" ("Libraries"), pressione "Adicionar Biblioteca" ("Add Library") e adicione a biblioteca "jme3-test-data".

Código de Amostra

package jme3test.helloworld;

import com.jme3.app.SimpleApplication;
import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;

/** Sample 11 - how to create fire, water, and explosion effects. */
public class HelloEffects extends SimpleApplication {

  public static void main(String[] args) {
    HelloEffects app = new HelloEffects();
    app.start();
  }

  @Override
  public void simpleInitApp() {

    ParticleEmitter fire = 
            new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 30);
    Material mat_red = new Material(assetManager, 
            "Common/MatDefs/Misc/Particle.j3md");
    mat_red.setTexture("Texture", assetManager.loadTexture(
            "Effects/Explosion/flame.png"));
    fire.setMaterial(mat_red);
    fire.setImagesX(2); 
    fire.setImagesY(2); // 2x2 texture animation
    fire.setEndColor(  new ColorRGBA(1f, 0f, 0f, 1f));   // red
    fire.setStartColor(new ColorRGBA(1f, 1f, 0f, 0.5f)); // yellow
    fire.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 2, 0));
    fire.setStartSize(1.5f);
    fire.setEndSize(0.1f);
    fire.setGravity(0, 0, 0);
    fire.setLowLife(1f);
    fire.setHighLife(3f);
    fire.getParticleInfluencer().setVelocityVariation(0.3f);
    rootNode.attachChild(fire);

    ParticleEmitter debris = 
            new ParticleEmitter("Debris", ParticleMesh.Type.Triangle, 10);
    Material debris_mat = new Material(assetManager, 
            "Common/MatDefs/Misc/Particle.j3md");
    debris_mat.setTexture("Texture", assetManager.loadTexture(
            "Effects/Explosion/Debris.png"));
    debris.setMaterial(debris_mat);
    debris.setImagesX(3); 
    debris.setImagesY(3); // 3x3 texture animation
    debris.setRotateSpeed(4);
    debris.setSelectRandomImage(true);
    debris.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 4, 0));
    debris.setStartColor(ColorRGBA.White);
    debris.setGravity(0, 6, 0);
    debris.getParticleInfluencer().setVelocityVariation(.60f);
    rootNode.attachChild(debris);
    debris.emitAllParticles();
  }
}

Você deveria ver um explosão que envia detritos voando, e um fogo. Mais código de exemplo se encontra aqui.

Animação de Textura e Variação

Inicie por escolher uma textura de material para seu efeito. Se você fornece ao emissor com um conjunto de texturas (veja imagem), ele pode usá-las tanto por variação (ordem aleatória), ou como passos de animação (ordem fixa).

Configurar texturas do emissor trabalha como você aprendeu nos capítulos anteriores. Desta vez você baseia o material na definição de material Particle.j3md. Vamos dar uma olhada mais de perto no material para o efeito de detritos.

    ParticleEmitter debris = 
            new ParticleEmitter("Debris", ParticleMesh.Type.Triangle, 10);
    Material debris_mat = new Material(assetManager, 
            "Common/MatDefs/Misc/Particle.j3md");
    debris_mat.setTexture("Texture", assetManager.loadTexture(
            "Effects/Explosion/Debris.png"));
    debris.setMaterial(debris_mat);
    debris.setImagesX(3); 
    debris.setImagesY(3); // 3x3 texture animation
    debris.setSelectRandomImage(true);
        ...
  1. Crie um material e carregue a textura
  2. Diga ao Emissor quantos passos de animação (x*y) a textura é dividida.
  3. A textura de detritos tem 3x3 quadros.
  4. Opcionalmente diga ao Emissor se os passos de animação são para serem aleatórios ou em ordem.
  5. Para os detritos os quadros reproduzem de forma aleatória.

Como você pode ver no exemplo de detritos animação de textura melhora os efeitos pois cada "chama" ou "pedaço de detrito" agora parece diferente. Também pense de efeitos mágicos ou elétricos, onde você cria animações muito interessantes por usar uma série de trovões de transformação ordenada; ou folhas voando ou flocos de neve, por exemplo.

O material do fogo é criado da mesma maneira, apenas usando a textura "Effects/Explosion/flame.png", com 2x2 passos de animação ordenados.

Texturas de partícula padrão

As seguintes texturas de partícula estão inclusas em test-data.jar. Você pode copiá-las e usá-las em seus próprios efeitos.

~Caminho da Textura Dimensão Previsualização
Effects/Explosion/Debris.png 3*3
Effects/Explosion/flame.png 2*2
Effects/Explosion/shockwave.png 1*1
Effects/Explosion/smoketrail.png 1*3
Effects/Smoke/Smoke.png 1*15

Copie elas em seu diretório assets/Effects para usá-las.

Criando Textura Customizada

Para seu jogo, você provavelmente criará texturas de partícula personalziadas. Olhe no exemplo do fogo de novo.

    ParticleEmitter fire = 
            new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 30);
    Material mat_red = new Material(assetManager, 
            "Common/MatDefs/Misc/Particle.j3md");
    mat_red.setTexture("Texture", assetManager.loadTexture(
            "Effects/Explosion/flame.png"));
    fire.setMaterial(mat_red);
    fire.setImagesX(2); 
    fire.setImagesY(2); // 2x2 texture animation
    fire.setEndColor(  new ColorRGBA(1f, 0f, 0f, 1f));   // red
    fire.setStartColor(new ColorRGBA(1f, 1f, 0f, 0.5f)); // yellow

Compare a textura com o efeito resultante.

  • Partes negras da imagem se tornam completamente transparentes.
  • Partes brancas/cinzas da imagem são transulcentes e ficam coloridas.
  • Você configura a cor usando setStartColor() e setEndColor().
  • Para o fogo é um gradiente de amarelo para vermelho.
  • Por padrão a animação é tocada em ordem e repete.

Crie uma textura escala de cinza em um editor gráfico e salve ele para seu diretório assets/Effects. Se você dividir um arquivo de imagem em x*y passos de animação, tenha certeza de que cada quadrado é de tamanho igual - da mesma forma que você vê nos exemplos aqui.

Parãmetros do Emissor

Um sistema de partícula é sempre centrado ao redor de um emissor.

Use o método setShape() para mudar a Forma do Emissor (EmitterShape):

    EmitterPointShape(Vector3f.ZERO) – particles emit from a point (default)
    EmitterSphereShape(Vector3f.ZERO,2f) – particles emit from a sphere-sized area
    EmitterBoxShape(new Vector3f(-1f,-1f,-1f),new Vector3f(1f,1f,1f)) – particles emit from a box-sized area

Exemplo:

emitter.setShape(new EmitterPointShape(Vector3f.ZERO));

Você cria diferentes efeitos por mudar os parâmetros do emissor:

~Parâmetro Método Padrão ~Descrição
number setNumParticles() N/A O número máximo de partículas simultaneamente visíveis. O valor é especificado pelo usuário no contrutor. Isto influencia a densidade e o tamanho da "trilha".
velocity getParticleInfluencer().setInitialVelocity() Vector3f.ZERO Especifica a um vetor quão rápido partículo se movem e qual a direção de início.
direção

setFacingVelocity() -
setRandomAngle() -
setFaceNormal() -
setRotateSpeed() || 0.2f -
false -
false -
Vector3f.NAN -
0.0f || Acessores opcionais que controlam em qual direção as partículas encaram enquanto voando. ||

lifetime

setHighLife() || 3f -
7f || Período do tempo mínimo e máximo antes que a partícula desapareça. ||

emission rate setParticlesPerSec() 20 Quantas novas partículas são emitidas por segundo.
color

setEndColor() || cinza || Configure para as mesmas cores ou para duas cores diferentes para um efeito de gradiente. ||

size

setEndSize() || 0.2f -
2f || Configure para dois diferentes valores para efeito de encolher/crescer, ou para o mesmo tamanho para efeito constante. ||

gravity setGravity() 0,1,0 Se partículas caem (positiva) ou voam (negativo). Configure para 0f para um efeito zero-g onde partículas continuam voando.

Você pode achar detalhes sobre parãmetros de efeito aqui. Adicione e modifique um parãmetro por vez, e experimente diferentes valores até que você consiga o efeito que você quer.

Dica: Use o SceneComposer no SDK da jMonkeyEngine para criar efeitos mais facilmente. Crie uma cena vazia e adiciona um objeto emissor para ela. Mude as propriedades do emissor e observe o resultado ao vivo. Você pode salvar efeitos criados como arquivo .j3o e carregá-los como cenas ou modelos.

Ecerício

Você pode "inverter" o efeito de fogo em uma pequena cascata? Aqui estão algumas dicas:

  • Mude a cor Vermelha e Amarela para Ciano e Azul
  • Inverta o vetor velocidade (direção) por usar um número negativo
  • Troca o tamanho do início e do fim.
  • Ative a gravidade por configurá-la para 0,1,0

Conclusão

Você tem aprendido que muitos efeitos diferentes podem ser criados por mudar os parãmetros e texturas de um objeto emissor geral.

Agora você prossegue para um outro capítulo excitante - a simulação de objetos físicos. Vamos disparar algumas bolas de canhão em uma parede de tijolos!

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-Share Alike 2.5 License.