1 /* 2 * Copyright (c) 2009-2010 jMonkeyEngine 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 package jme3test.effect; 34 35 import com.jme3.app.SimpleApplication; 36 import com.jme3.effect.ParticleEmitter; 37 import com.jme3.effect.ParticleMesh.Type; 38 import com.jme3.effect.shapes.EmitterSphereShape; 39 import com.jme3.material.Material; 40 import com.jme3.math.ColorRGBA; 41 import com.jme3.math.FastMath; 42 import com.jme3.math.Quaternion; 43 import com.jme3.math.Vector3f; 44 import com.jme3.scene.Node; 45 46 public class TestExplosionEffect extends SimpleApplication { 47 48 private float time = 0; 49 private int state = 0; 50 private Node explosionEffect = new Node("explosionFX"); 51 private ParticleEmitter flame, flash, spark, roundspark, smoketrail, debris, 52 shockwave; 53 54 55 private static final int COUNT_FACTOR = 1; 56 private static final float COUNT_FACTOR_F = 1f; 57 58 private static final boolean POINT_SPRITE = true; 59 private static final Type EMITTER_TYPE = POINT_SPRITE ? Type.Point : Type.Triangle; 60 main(String[] args)61 public static void main(String[] args){ 62 TestExplosionEffect app = new TestExplosionEffect(); 63 app.start(); 64 } 65 createFlame()66 private void createFlame(){ 67 flame = new ParticleEmitter("Flame", EMITTER_TYPE, 32 * COUNT_FACTOR); 68 flame.setSelectRandomImage(true); 69 flame.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f, (float) (1f / COUNT_FACTOR_F))); 70 flame.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f)); 71 flame.setStartSize(1.3f); 72 flame.setEndSize(2f); 73 flame.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); 74 flame.setParticlesPerSec(0); 75 flame.setGravity(0, -5, 0); 76 flame.setLowLife(.4f); 77 flame.setHighLife(.5f); 78 flame.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 7, 0)); 79 flame.getParticleInfluencer().setVelocityVariation(1f); 80 flame.setImagesX(2); 81 flame.setImagesY(2); 82 Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); 83 mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png")); 84 mat.setBoolean("PointSprite", POINT_SPRITE); 85 flame.setMaterial(mat); 86 explosionEffect.attachChild(flame); 87 } 88 createFlash()89 private void createFlash(){ 90 flash = new ParticleEmitter("Flash", EMITTER_TYPE, 24 * COUNT_FACTOR); 91 flash.setSelectRandomImage(true); 92 flash.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, (float) (1f / COUNT_FACTOR_F))); 93 flash.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f)); 94 flash.setStartSize(.1f); 95 flash.setEndSize(3.0f); 96 flash.setShape(new EmitterSphereShape(Vector3f.ZERO, .05f)); 97 flash.setParticlesPerSec(0); 98 flash.setGravity(0, 0, 0); 99 flash.setLowLife(.2f); 100 flash.setHighLife(.2f); 101 flash.setInitialVelocity(new Vector3f(0, 5f, 0)); 102 flash.setVelocityVariation(1); 103 flash.setImagesX(2); 104 flash.setImagesY(2); 105 Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); 106 mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flash.png")); 107 mat.setBoolean("PointSprite", POINT_SPRITE); 108 flash.setMaterial(mat); 109 explosionEffect.attachChild(flash); 110 } 111 createRoundSpark()112 private void createRoundSpark(){ 113 roundspark = new ParticleEmitter("RoundSpark", EMITTER_TYPE, 20 * COUNT_FACTOR); 114 roundspark.setStartColor(new ColorRGBA(1f, 0.29f, 0.34f, (float) (1.0 / COUNT_FACTOR_F))); 115 roundspark.setEndColor(new ColorRGBA(0, 0, 0, (float) (0.5f / COUNT_FACTOR_F))); 116 roundspark.setStartSize(1.2f); 117 roundspark.setEndSize(1.8f); 118 roundspark.setShape(new EmitterSphereShape(Vector3f.ZERO, 2f)); 119 roundspark.setParticlesPerSec(0); 120 roundspark.setGravity(0, -.5f, 0); 121 roundspark.setLowLife(1.8f); 122 roundspark.setHighLife(2f); 123 roundspark.setInitialVelocity(new Vector3f(0, 3, 0)); 124 roundspark.setVelocityVariation(.5f); 125 roundspark.setImagesX(1); 126 roundspark.setImagesY(1); 127 Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); 128 mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/roundspark.png")); 129 mat.setBoolean("PointSprite", POINT_SPRITE); 130 roundspark.setMaterial(mat); 131 explosionEffect.attachChild(roundspark); 132 } 133 createSpark()134 private void createSpark(){ 135 spark = new ParticleEmitter("Spark", Type.Triangle, 30 * COUNT_FACTOR); 136 spark.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, (float) (1.0f / COUNT_FACTOR_F))); 137 spark.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f)); 138 spark.setStartSize(.5f); 139 spark.setEndSize(.5f); 140 spark.setFacingVelocity(true); 141 spark.setParticlesPerSec(0); 142 spark.setGravity(0, 5, 0); 143 spark.setLowLife(1.1f); 144 spark.setHighLife(1.5f); 145 spark.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 20, 0)); 146 spark.getParticleInfluencer().setVelocityVariation(1); 147 spark.setImagesX(1); 148 spark.setImagesY(1); 149 Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); 150 mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/spark.png")); 151 spark.setMaterial(mat); 152 explosionEffect.attachChild(spark); 153 } 154 createSmokeTrail()155 private void createSmokeTrail(){ 156 smoketrail = new ParticleEmitter("SmokeTrail", Type.Triangle, 22 * COUNT_FACTOR); 157 smoketrail.setStartColor(new ColorRGBA(1f, 0.8f, 0.36f, (float) (1.0f / COUNT_FACTOR_F))); 158 smoketrail.setEndColor(new ColorRGBA(1f, 0.8f, 0.36f, 0f)); 159 smoketrail.setStartSize(.2f); 160 smoketrail.setEndSize(1f); 161 162 // smoketrail.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f)); 163 smoketrail.setFacingVelocity(true); 164 smoketrail.setParticlesPerSec(0); 165 smoketrail.setGravity(0, 1, 0); 166 smoketrail.setLowLife(.4f); 167 smoketrail.setHighLife(.5f); 168 smoketrail.setInitialVelocity(new Vector3f(0, 12, 0)); 169 smoketrail.setVelocityVariation(1); 170 smoketrail.setImagesX(1); 171 smoketrail.setImagesY(3); 172 Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); 173 mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/smoketrail.png")); 174 smoketrail.setMaterial(mat); 175 explosionEffect.attachChild(smoketrail); 176 } 177 createDebris()178 private void createDebris(){ 179 debris = new ParticleEmitter("Debris", Type.Triangle, 15 * COUNT_FACTOR); 180 debris.setSelectRandomImage(true); 181 debris.setRandomAngle(true); 182 debris.setRotateSpeed(FastMath.TWO_PI * 4); 183 debris.setStartColor(new ColorRGBA(1f, 0.59f, 0.28f, (float) (1.0f / COUNT_FACTOR_F))); 184 debris.setEndColor(new ColorRGBA(.5f, 0.5f, 0.5f, 0f)); 185 debris.setStartSize(.2f); 186 debris.setEndSize(.2f); 187 188 // debris.setShape(new EmitterSphereShape(Vector3f.ZERO, .05f)); 189 debris.setParticlesPerSec(0); 190 debris.setGravity(0, 12f, 0); 191 debris.setLowLife(1.4f); 192 debris.setHighLife(1.5f); 193 debris.setInitialVelocity(new Vector3f(0, 15, 0)); 194 debris.setVelocityVariation(.60f); 195 debris.setImagesX(3); 196 debris.setImagesY(3); 197 Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); 198 mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/Debris.png")); 199 debris.setMaterial(mat); 200 explosionEffect.attachChild(debris); 201 } 202 createShockwave()203 private void createShockwave(){ 204 shockwave = new ParticleEmitter("Shockwave", Type.Triangle, 1 * COUNT_FACTOR); 205 // shockwave.setRandomAngle(true); 206 shockwave.setFaceNormal(Vector3f.UNIT_Y); 207 shockwave.setStartColor(new ColorRGBA(.48f, 0.17f, 0.01f, (float) (.8f / COUNT_FACTOR_F))); 208 shockwave.setEndColor(new ColorRGBA(.48f, 0.17f, 0.01f, 0f)); 209 210 shockwave.setStartSize(0f); 211 shockwave.setEndSize(7f); 212 213 shockwave.setParticlesPerSec(0); 214 shockwave.setGravity(0, 0, 0); 215 shockwave.setLowLife(0.5f); 216 shockwave.setHighLife(0.5f); 217 shockwave.setInitialVelocity(new Vector3f(0, 0, 0)); 218 shockwave.setVelocityVariation(0f); 219 shockwave.setImagesX(1); 220 shockwave.setImagesY(1); 221 Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); 222 mat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/shockwave.png")); 223 shockwave.setMaterial(mat); 224 explosionEffect.attachChild(shockwave); 225 } 226 227 @Override simpleInitApp()228 public void simpleInitApp() { 229 createFlame(); 230 createFlash(); 231 createSpark(); 232 createRoundSpark(); 233 createSmokeTrail(); 234 createDebris(); 235 createShockwave(); 236 explosionEffect.setLocalScale(0.5f); 237 renderManager.preloadScene(explosionEffect); 238 239 cam.setLocation(new Vector3f(0, 3.5135868f, 10)); 240 cam.setRotation(new Quaternion(1.5714673E-4f, 0.98696727f, -0.16091813f, 9.6381607E-4f)); 241 242 rootNode.attachChild(explosionEffect); 243 } 244 245 @Override simpleUpdate(float tpf)246 public void simpleUpdate(float tpf){ 247 time += tpf / speed; 248 if (time > 1f && state == 0){ 249 flash.emitAllParticles(); 250 spark.emitAllParticles(); 251 smoketrail.emitAllParticles(); 252 debris.emitAllParticles(); 253 shockwave.emitAllParticles(); 254 state++; 255 } 256 if (time > 1f + .05f / speed && state == 1){ 257 flame.emitAllParticles(); 258 roundspark.emitAllParticles(); 259 state++; 260 } 261 262 // rewind the effect 263 if (time > 5 / speed && state == 2){ 264 state = 0; 265 time = 0; 266 267 flash.killAllParticles(); 268 spark.killAllParticles(); 269 smoketrail.killAllParticles(); 270 debris.killAllParticles(); 271 flame.killAllParticles(); 272 roundspark.killAllParticles(); 273 shockwave.killAllParticles(); 274 } 275 } 276 277 } 278