Particle Explosion with Android

Ever wondered how explosions are created? Let’s take a little detour and try to implement a basic particle explosion.

An explosion is nothing more than a bunch of particles (be them pixels, small shapes or images) scattered across the screen, originating from a single point. Not all the time but mostly and for the sake of simplicity we’ll assume that all particles originate from a single point.

Just think of fireworks. A tiny little rocket shoots up and explodes into hundreds of sparkling little stars that fade out as they fall down. What happens is that a huge force in the center of the rocket rips the body apart (thus creating particles) and scatters them randomly around the point of explosion.

To make it simple we’ll create a few particles, we will place them in one place (the origin) and give them random forces. A force is a vector quantity. It means that it has magnitude and direction. The magnitude will determine its speed and its direction will tell the particle which way to go.

The Particle

The class file:

public class Particle {

	public static final int STATE_ALIVE = 0;	// particle is alive
	public static final int STATE_DEAD = 1;		// particle is dead
	
	public static final int DEFAULT_LIFETIME 	= 200;	// play with this
	public static final int MAX_DIMENSION		= 5;	// the maximum width or height
	public static final int MAX_SPEED			= 10;	// maximum speed (per update)

	private int state;			// particle is alive or dead
	private float width;		// width of the particle
	private float height;		// height of the particle
	private float x, y;			// horizontal and vertical position
	private double xv, yv;		// vertical and horizontal velocity
	private int age;			// current age of the particle
	private int lifetime;		// particle dies when it reaches this value
	private int color;			// the color of the particle
	private Paint paint;		// internal use to avoid instantiation
}

The particle is nothing more than a little rectangle (this can be an image, circle or any other shape, but in our case we use a rectangle) with a few properties.

It has a state. This indicates whether the particle is alive or dead. A particle is alive when its color is not black (it hasn’t faded) and its age hasn’t reached its lifetime. More on this a bit later.

It has a position. It’s position in a 2D coordinate system is represented by 2 points: x and y.

It also has a speed and a direction. As you recall speed is a vector so it has 2 components in 2D. In 3D it will also have the z component but we stay in 2D for now. To keep it simple now we add two properties for this. vx and vy

The age of the particle is it’s 0 in the beginning and is incremented at each update.

The lifetime is the maximum age a particle can reach before it dies.

The rest are color and paint. These are for drawing only.

If you recall the previous entries, the game update is nothing more than calling the update methods of every entities in the game and displaying them. The update method of the particle is pretty simple.

But first we need to create the particle:

public Particle(int x, int y) {
	this.x = x;
	this.y = y;
	this.state = Particle.STATE_ALIVE;
	this.widht = rndInt(1, MAX_DIMENSION);
	this.height = this.widht;
	this.lifetime = DEFAULT_LIFETIME;
	this.age = 0;
	this.xv = (rndDbl(0, MAX_SPEED * 2) - MAX_SPEED);
	this.yv = (rndDbl(0, MAX_SPEED * 2) - MAX_SPEED);
	// smoothing out the diagonal speed
	if (xv * xv + yv * yv > MAX_SPEED * MAX_SPEED) {
		xv *= 0.7;
		yv *= 0.7;
	}
	this.color = Color.argb(255, rndInt(0, 255), rndInt(0, 255), rndInt(0, 255));
	this.paint = new Paint(this.color);
}

Check the creation of a particle and it should be straight forward.

You will notice that a particle is created at position x,y.

The state is set to alive.
We want to randomise the size of the rectangles because an explosion creates particles in different sizes and shapes but we’ll just randomise the size and colour.
I have written a few helper methods that give me random numbers, for this check the complete source code.

Next the lifetime is set. Every particle will have the same lifetime.

The age is 0 of course as the particle has just been born.

Next is the interesting bit. It’s very amateurish. To set the speed I have used 2 random numbers for the 2 components of the speed vector (vx and vy). The smoothing is needed because if both components are near the maximum value then the resulting magnitude will be over the max speed. You could use simple trigonometric functions with a random degree instead of this.

The las thing to set is the color which again is randomised.

There you have it.

The update() method for the particle.

public void update() {
	if (this.state != STATE_DEAD) {
		this.x += this.xv;
		this.y += this.yv;
		
		// extract alpha
		int a = this.color >>> 24;
		a -= 2; // fade by 2
		if (a <= 0) { // if reached transparency kill the particle
			this.state = STATE_DEAD;
		} else {
			this.color = (this.color & 0x00ffffff) + (a << 24);		// set the new alpha
			this.paint.setAlpha(a);
			this.age++; // increase the age of the particle
		}
		if (this.age >= this.lifetime) {	// reached the end if its life
			this.state = STATE_DEAD;
    }
	}
}

It’s pretty simple. Every update, the position is set according to the speed and the alpha component of the particle’s color is decremented. In other words the particle is being faded.

If the age exceeded the lifetime or the opacity is 0 (that means that it is completely transparent) the particle is declared dead.

If you wonder about the magic with colours, it is quite simple once you get the bitwise operators. Don’t worry, I’m rubbish as well, just make sure you know where to look. Here is a good explanation of colour components and how to use bitwise operators to manipulate them: http://lab.polygonal.de/2007/05/10/bitwise-gems-fast-integer-math. It’s faster than using the objects but you can safely use the android methods too.

Just as a side note on colours

You can specify colours in Android as an int. If you’re familiar with rgb and argb that is great.
rgb is 24 bits color while argb is 32 bits. It also has the alpha component which is transparency/opacity.

Opacity values: 0 = transparent, 255 = completely opaque.

To represent an int in hex you just prefix it with 0x. A color in hex is simple: 0x00FF00 is green for example. The pattern is: 0xRRGGBB (Red, Green, Blue). Now to add the alpha you will add it to the beginning. 0xAARRGGBB.
Because it is in hex, the values are between 00 and FF. 0 being 0 and FF being 255 in decimal.
When you create a colour out of components like color(a, r, g, b) (for example: new Color(125, 255, 0, 0) creates a semi transparent red), you can simply create it with an integer expressed in hex like this: new Color(0x80FF0000);

This is how you would extract the components of an argb colour.

int color = 0xff336699;
int alpha = color >>> 24;
int red   = color >>> 16 & 0xFF;
int green = color >>>  8 & 0xFF;
int blue  = color & 0xFF;

The draw() method is simple again.

	public void draw(Canvas canvas) {
		paint.setColor(this.color);
		canvas.drawRect(this.x, this.y, this.x + this.widht, this.y + this.height, paint);
	}

At this stage try to create some particles in your game panel and see what happens.

The Explosion

The explosion is nothing more than hundreds of particles originating from one place, the origin.

Explosion

In the image above you see the first 4 updates of a simple explosion. All the particles have the same speed but they spread out in different directions. Each circle is one update.

The main properties of an explosion are:

public class Explosion {
	
	public static final int STATE_ALIVE 	= 0;	// at least 1 particle is alive
	public static final int STATE_DEAD 		= 1;	// all particles are dead
	
	private Particle[] particles;			// particles in the explosion
	private int x, y;						// the explosion's origin
	private int size;						// number of particles
	private int state;						// whether it's still active or not
}

It contains an array of particles. The size is the number of particles. An explosion is alive if it has at least one particle alive.

The update is extremely simple. It iterates through all the particles and calls the update() method on each particle. The draw() ditto.

In our application we will create explosions on the screen where we touch it.
The constructor is very simple:

	public Explosion(int particleNr, int x, int y) {
		Log.d(TAG, "Explosion created at " + x + "," + y);
		this.state = STATE_ALIVE;
		this.particles = new Particle[particleNr];
	 	for (int i = 0; i < this.particles.length; i++) {
			Particle p = new Particle(x, y);
			this.particles[i] = p;
		}
	 	this.size = particleNr;
	}

The array of particles is being filled at the touch down position.

In our application we will allow up to 10 explosions. So in the MainGamePanel we declare an array of explosions.

	private Explosion[] explosions;

In the surfaceCreated method we instantiate the array and fill it with null.

		explosions = new Explosion[10];
		for (int i = 0; i < explosions.length; i++) {
			explosions[i] = null;
		}

The onTouchEvent is where we create explosions.

	public boolean onTouchEvent(MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			// check if explosion is null or if it is still active
			int currentExplosion = 0;
			Explosion explosion = explosions[currentExplosion];
			while (explosion != null && explosion.isAlive() && currentExplosion < explosions.length) {
				currentExplosion++;
				explosion = explosions[currentExplosion];
			}
			if (explosion == null || explosion.isDead()) {
				explosion = new Explosion(EXPLOSION_SIZE, (int)event.getX(), (int)event.getY());
				explosions[currentExplosion] = explosion;
			}
		}
		return true;
	}

What we do is iterate through the explosions and when we find the first null (this means we never used it for an instance) or the first dead explosion we create a new one at the touch position.

The update and render methods are straight forward. Iterate through the explosions and if they are not null and are alive then call their update and draw methods respectively.

In the final code I added a border for the screen as the wall and added a basic collision detection for the particles so they bounce off the walls. The wall is being transmitted as a reference and the update method checks for collision with it. Use it as an exercise and remove the collision and try attaching an image to the particle instead of being a rectangle. To create explosions just click on the screen.

It should look like this:

Explosion Screenshot

Explore the code and have fun.

LinkedInRedditTumblrDiggTechnorati FavoritesShare

16 Responses - Add Yours+

  1. Diksha says:

    how to set the image rather than creating the particle..???

  2. Bill Lahti says:

    Very nice tutorial and such an interesting visual effect. Thanks so much for sharing this information.

    Is it okay to use your code in other applications? I did not see any license information in any of the files.

  3. Chupo_cro says:

    Is there a bug in the code? Seems as only one explosion can exist at the same time.

  4. mxbYeah says:

    is it possible to do this by extending View instead of SurfaceView implements
    SurfaceHolder.Callback and posting invalidate during the update calls?

  5. shirish says:

    The while condition should probably have currentExplosion < explosion.length – 1.
    other wise I was getting a force close , may be because accessing an out of bounds array element

    while (explosion != null && explosion.isAlive() && currentExplosion < explosions.length – 1) {
    currentExplosion++;
    explosion = explosions[currentExplosion];
    }

  6. Rob says:

    Probably one of the most thorough android tutorials I’ve read.

    Thank you for giving up your time

  7. rob says:

    Your graph has the Vx and Vy backwards. V*sin(a) would give you the vertical projection.

  8. Avario says:

    These tutorials are so great, the best I can find anywhere. Please keep them coming and thank you very much for sharing.

  9. Thomas says:

    I suggest you move the initialization of your explosions array back into the MainGamePanel constructor. If you do it in surfaceCreated() you will lose state for your particle explosions and they will disappear when you return to the activity after pressing home.

    Thanks again for the great example :)

    • Impaler says:

      Thanks for pointing it out. I will do that so the state will be saved and restored properly.
      Also one should bear in mind that these code examples are proof of concepts and I am trying to get the core of the functionality across and the architecture might not suite certain scenarios.

      Will give an update when the changes have been made.

  10. rock84 says:

    Hey, these are great. Been following since the first post. I haven’t finished this one though because I’m having trouble adding a particle to my game panel.

    • Impaler says:

      Did you try taking the code and stripping out the explosion? Try doing that and have just one particle in the onTouchEvent() and see if you manage to do that.

  11. Foxx says:

    Ahaaa o added the majority of these tutorials together and now i have a droid that bounces around that if you press him he ‘explodes’ and then if you touch the bottom of them screen you can move the droid about the y-axis

  12. pramod says:

    Thanks for the great tutorial,But I am finding the difficulty to replace these rectangles by my own star image.Please help.