So here are just two classes in my (super bare)particle engine. Basically to use, just make an arraylist of ParticleEmitters in the testing class, and then iterate through that for the moving and drawing methods.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.geom.Point2D;
import java.util.Random;
public class Particle
{
final int lifetime = 30; Color color; double age = 0; int radius = 1;
Random r = new Random();
Point2D.Float movement= new Point2D.Float(0,0);
public Particle(Point2D.Float loc, double angle_deg, Color color, float speed, int radius)
{
this.loc = loc; this.radius=radius; this.color = color;
movement.x = speed * (float)Math.cos(Math.PI * angle_deg / 180);
movement.y = speed * (float)Math.sin(Math.PI * angle_deg / 180);
}
Point2D.Float loc;
public boolean shouldRemove = false;
public void Move()
{
loc.x += movement.x; loc.y += movement.y;
age ++;
if (age >= lifetime) {
shouldRemove = true;
}
}
public void Draw(Graphics g)
{
Color col = new Color(color.getRed(), color.getGreen(), color.getBlue(),
(int)Math.max(255 - (age / lifetime * 255), 0));
g.setColor(col);
g.fillOval((int)(loc.x - 1), (int)(loc.y - 1),radius, radius);
}
}
import java.awt.Color;
import java.awt.Graphics;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Random;
public class ParticleEmitter
{
public ArrayList<Particle> particles = new ArrayList<Particle>();
protected Random r= new Random();
/// <summary>
///Initialize particle emitter
/// </summary>
public ParticleEmitter(Point2D.Float loc, Color colorA, Color colorB, int population)
{
if (population > 0)
{
//used to be min of 10
int n = Math.max(10, (int)Math.floor(Math.sqrt(population)));
int scatter = (int)Math.floor(Math.sqrt(population) / 4) + 5;
for (int i = 0; i < n; i++)
{
//alternate colors
Color c = colorA;
//if even
if (i%2 == 0) c = colorB;
//slightly random centering and angle and size
Point2D.Float pt_new=
new Point2D.Float(loc.x+ randInt(-scatter, scatter),
loc.y+ randInt(-scatter, scatter));
particles.add(new Particle(pt_new,
randInt(0, 360), c,
(float)Math.max(1, Math.sqrt(population) / 10) * 1f, randInt(2, 6)));
}
}
}
public ParticleEmitter() {
// TODO Auto-generated constructor stub
}
/// <summary>
///draws all the particles from this particle emitter
/// </summary>
public void DrawParticles(Graphics g)
{
//basically, a foreach loop
for(Particle p : particles)
{
p.Draw(g);
}
}
/// <summary>
///steps particles one frame forward
/// </summary>
public void MoveParticles()
{
//basically, a foreach loop
for(Particle p : particles)
{
p.Move();
}
for (int i = 0; i < particles.size(); i++)
{
if (particles.get(i).shouldRemove)
particles.remove(i);
}
}
// a helper method to generate random number in a range
public int randInt(int min, int max)
{
return r.nextInt((max - min) + 1) + min;
}
}
It looks pretty good…