2D Particle System¶
Emitter API Method Reference¶
| Method Signature | Return Type | Description |
|---|---|---|
setTimeToLive(int duration) |
void |
Sets lifespan of the emitter in milliseconds (or -1 for infinite). |
setMaxParticles(int count) |
void |
Limits maximum concurrent alive particles spawned by this emitter. |
setSpawnRate(int delayMs) |
void |
Sets the interval delay between successive particle spawns. |
setParticleType(ParticleType type) |
void |
Sets particle primitive (RECTANGLE, ELLIPSE, LINE, SPRITE). |
onFinished(EmitterFinishedListener c) |
void |
Listener invoked when a finite emitter completes and expires. |
activate() / deactivate() |
void |
Enables or pauses particle emission. |
The LITIENGINE particle system allows you to create dynamic visual effects by emitting and animating large numbers of small sprites or shapes. Use it for fire, smoke, explosions, magic spells, and environmental effects.
How Particles Work¶
- An Emitter spawns particles at a defined rate
- Each Particle has properties like position, velocity, size, color, and lifetime
- Particles are updated every tick and rendered to the screen
- When a particle's lifetime expires, it is removed
Creating an Emitter¶
Using utiLITI¶
- Add an Emitter entity to your map
- Configure emitter properties in the Properties panel
- Set particle appearance, behavior, and timing
Using Code¶
public class FireEmitter extends Emitter {
public FireEmitter(double x, double y) {
super(x, y);
// Configure emitter
this.getData().setSpawnRate(30); // Particles per second
this.getData().setEmitterDuration(0); // 0 = infinite
this.getData().setMaxParticles(100);
// Configure particles
this.getData().setParticleWidth(16);
this.getData().setParticleHeight(16);
this.getData().setMinTTL(500); // Min lifetime (ms)
this.getData().setMaxTTL(1000); // Max lifetime (ms)
// Particle appearance
this.getData().setSpritesheet(Resources.spritesheets().get("fire-particle"));
// Start emitting
this.activate();
}
}
Particle Properties¶
Lifetime¶
// Particle lives between 500-1000ms
emitter.getData().setMinTTL(500);
emitter.getData().setMaxTTL(1000);
Velocity and Movement¶
// Upward movement with random variance
emitter.getData().setVelocityXMin(-20);
emitter.getData().setVelocityXMax(20);
emitter.getData().setVelocityYMin(-50);
emitter.getData().setVelocityYMax(-30);
// Acceleration (gravity, wind)
emitter.getData().setAccelerationXMin(-5);
emitter.getData().setAccelerationXMax(5);
emitter.getData().setAccelerationYMin(-10);
emitter.getData().setAccelerationYMax(-5);
Size and Scale¶
// Initial size
emitter.getData().setParticleWidth(8);
emitter.getData().setParticleHeight(8);
// Scale over lifetime (start large, shrink)
emitter.getData().setMinStartScale(2.0f);
emitter.getData().setMaxStartScale(2.5f);
emitter.getData().setMinEndScale(0.1f);
emitter.getData().setMaxEndScale(0.3f);
Color and Opacity¶
// Color transitions over lifetime
emitter.getData().setStartColor(Color.ORANGE);
emitter.getData().setEndColor(Color.RED);
// Fade out
emitter.getData().setMinStartAlpha(1.0f);
emitter.getData().setMaxStartAlpha(1.0f);
emitter.getData().setMinEndAlpha(0.0f);
emitter.getData().setMaxEndAlpha(0.0f);
Particle Types¶
Sprite Particles¶
// Use a spritesheet for particle visuals
Spritesheet sheet = Resources.spritesheets().get("sparkle");
emitter.getData().setSpritesheet(sheet);
Shape Particles¶
// Render particles as shapes
emitter.getData().setParticleType(ParticleType.SQUARE);
emitter.getData().setParticleType(ParticleType.CIRCLE);
emitter.getData().setParticleType(ParticleType.TRIANGLE);
Text Particles¶
// Render particles as text
emitter.getData().setParticleType(ParticleType.TEXT);
emitter.getData().setText("");
emitter.getData().setFont(Resources.fonts().get("gamefont.ttf", 12f));
Emitter Behavior¶
One-Shot Effect¶
// Emit burst of particles once
emitter.getData().setSpawnAmount(50);
emitter.getData().setEmitterDuration(100);
emitter.getData().setLoop(false);
Continuous Effect¶
// Continuous emission
emitter.getData().setSpawnRate(20); // Particles per second
emitter.getData().setEmitterDuration(0); // Infinite
emitter.getData().setLoop(true);
Burst Emission¶
// Emit bursts at intervals
emitter.getData().setSpawnAmount(30);
emitter.getData().setSpawnRate(0); // Not continuous
emitter.getData().setBurstMode(true);
emitter.getData().setBurstInterval(2000); // Every 2 seconds
Adding Emitters to Environment¶
Custom Particles¶
Create custom particle behavior by extending Particle:
public class SparkParticle extends Particle {
public SparkParticle() {
super();
this.setWidth(4);
this.setHeight(4);
this.setColor(Color.YELLOW);
}
@Override
public void update(float updateRatio) {
super.update(updateRatio);
// Custom behavior: flicker
if (Game.random().nextFloat() > 0.5f) {
this.setVisible(!this.isVisible());
}
}
}
Particle Recipes Cookbook¶
Below are complete, copy-paste ready emitter classes for common 2D visual effects:
1. Torch & Campfire Flame¶
import java.awt.Color;
import de.gurkenlabs.litiengine.graphics.emitters.Emitter;
import de.gurkenlabs.litiengine.graphics.emitters.particles.ParticleType;
public class CampfireEmitter extends Emitter {
public CampfireEmitter(double x, double y) {
super(x, y);
this.setWidth(16);
this.setHeight(16);
this.getData().setParticleType(ParticleType.CIRCLE);
this.getData().setSpawnRate(25);
this.getData().setParticleTTLMin(400);
this.getData().setParticleTTLMax(800);
// Float upwards with slight horizontal jitter
this.getData().setVelocityXMin(-10);
this.getData().setVelocityXMax(10);
this.getData().setVelocityYMin(-45);
this.getData().setVelocityYMax(-20);
// Fade from bright yellow/orange to dark smoky red
this.getData().setColor(new Color(255, 200, 50, 220));
this.getData().setFade(true);
this.getData().setFadeColor(new Color(220, 50, 20, 0));
}
}
2. Explosion / Impact Burst¶
import java.awt.Color;
import de.gurkenlabs.litiengine.graphics.emitters.Emitter;
import de.gurkenlabs.litiengine.graphics.emitters.particles.ParticleType;
public class ExplosionEmitter extends Emitter {
public ExplosionEmitter(double x, double y) {
super(x, y);
this.setWidth(10);
this.setHeight(10);
this.getData().setParticleType(ParticleType.SQUARE);
this.getData().setSpawnAmount(60);
this.getData().setEmitterDuration(150);
this.getData().setLoop(false);
this.getData().setParticleTTLMin(200);
this.getData().setParticleTTLMax(500);
// Radial explosive velocity in all directions
this.getData().setVelocityXMin(-120);
this.getData().setVelocityXMax(120);
this.getData().setVelocityYMin(-120);
this.getData().setVelocityYMax(120);
this.getData().setColor(new Color(255, 120, 0, 255));
this.getData().setFade(true);
this.getData().setFadeColor(new Color(80, 80, 80, 0));
}
}
3. Rain Weather Emitter¶
import java.awt.Color;
import de.gurkenlabs.litiengine.Game;
import de.gurkenlabs.litiengine.graphics.emitters.Emitter;
import de.gurkenlabs.litiengine.graphics.emitters.particles.ParticleType;
public class RainEmitter extends Emitter {
public RainEmitter() {
super(0, 0);
// Span across the map or active camera viewport
this.setWidth(Game.world().environment().getMap().getSizeInPixels().getWidth());
this.setHeight(10);
this.getData().setParticleType(ParticleType.RECTANGLE);
this.getData().setParticleWidth(1);
this.getData().setParticleHeight(8);
this.getData().setSpawnRate(80);
this.getData().setLoop(true);
// Fall downwards with slight wind angle
this.getData().setVelocityXMin(-15);
this.getData().setVelocityXMax(-5);
this.getData().setVelocityYMin(180);
this.getData().setVelocityYMax(240);
this.getData().setColor(new Color(150, 190, 255, 160));
}
}
Performance Tips¶
- Limit max particles: Set reasonable
maxParticlesvalues - Use sprite sheets: More efficient than shapes for complex particles
- Recycle emitters: Reuse emitters instead of creating new ones
- Suspend when off-screen: Emitters outside camera view should be suspended
See Also¶
- Dynamic Lighting - Lighting effects
- Render Engine - Rendering system