class SparksLayer extends Layer { float gravity = 5.0f; float drag = 0.5f; float sparkMass = 10.0f; int sparkColor = color(0xff, 0xff, 0xff); float maxV = 8; float lifetimeMin = 5; float lifetimeMax = 25; ParticleSystem system; ArrayList sparks = new ArrayList(); int maxPositions = 20; int nTicks = 2; SparksLayer(PApplet parent) { super(parent); } void setup() { system = new ParticleSystem(gravity, drag); background(0); } void draw() { background(0, 0); smooth(); if (mousePressed) { float nSparks = random(1, 20); for (int i = 0; i < nSparks; i++) { makeSpark(); } } advanceTime(nTicks); ListIterator it = sparks.listIterator(); setVisible(false); while (it.hasNext()) { Spark spark = (Spark) it.next(); if (spark.lifetime < spark.particle.age()) { system.removeParticle(spark.particle); it.remove(); } else { setVisible(true); drawSpark(spark); } } } void advanceTime(int n) { for (int i = 0; i < n; i++) { system.tick(); ListIterator it = sparks.listIterator(); while (it.hasNext()) { Spark spark = (Spark) it.next(); ArrayList positions = spark.pastPositions; Vector3D position = spark.particle.position(); positions.add(new Vector3D(position.x(), position.y(), position.z())); } } ListIterator it = sparks.listIterator(); while (it.hasNext()) { Spark spark = (Spark) it.next(); int nRemove = spark.pastPositions.size() - maxPositions; ListIterator positions = spark.pastPositions.listIterator(); for (int i = 0; i < nRemove; i++) { positions.next(); positions.remove(); } } } void drawSpark(Spark spark) { stroke(sparkColor); int index = spark.pastPositions.size() - 1; Vector3D p1 = (Vector3D) spark.pastPositions.get(index--); int indexLimit = index - spark.tailLength; if (indexLimit < 0) { indexLimit = 0; } int loopCount = 0; while (index > indexLimit) { Vector3D p2 = (Vector3D) spark.pastPositions.get(index); if (loopCount < 2) { strokeWeight(2); } else { strokeWeight(1); } line(p1.x(), p1.y(), p2.x(), p2.y()); p1 = p2; loopCount++; index--; } } void makeSpark() { Particle p = system.makeParticle(sparkMass, mouseX, mouseY, 0); float xv = random(-maxV, maxV); float yv = random(-maxV, maxV); p.velocity().set(xv, yv, 0); sparks.add(new Spark(p)); } class Spark { Particle particle; float lifetime; int tailLength; ArrayList pastPositions = new ArrayList(); Spark(Particle p) { this.particle = p; this.lifetime = random(lifetimeMin, lifetimeMax); this.tailLength = (int)random(3, 6); } } }