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

Particle

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. Its 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 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.


A 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 Diagram

Explosion Diagram

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

Explosion

Explore the code and have fun.

Download it here (TBD).