Implementing Particles with melonJS

Andre Antonio Schmitz

June 24th, 2014

With the popularity of games on smartphones and browsers, 2D gaming is back on the scene, recalling the classic age of the late '80s and early '90s. At that time, most games used animation techniques with images (sprite sheets) to display special effects such as explosions, fire, or magic. In current games we can use particle systems, generating random and interesting visual effects in them. In this post I will briefly describe what a particle system is and how to implement models using the HTML5 engine melonJS.

Note: Although the examples are specific to the melonJS game engine using JavaScript as a programming language, the concepts and ideas can be adapted for other languages ​​or game engines as well.

Particle systems

A particle system is a technique used to simulate a variety of special visual effects like sparks, dust, smoke, fire, explosions, rain, stars, falling snow, glowing trails, and many others. Basically, a particle system consists of emitters and the particles themselves.

The particles are small objects or textures that have different properties, such as:

  • Position (x, y)
  • Velocity (vx, vy)
  • Scale
  • Angle
  • Transparency (alpha)
  • Texture (sprite ou cor
  • Lifetime

These particles perform some functions associated with their properties (movement, rotation, scaling, change in transparency, and so on) for a period of time, and are removed from the game after this interval (or they are returned to a pool of particles for reuse, ensuring better performance).

According to how the particle system is implemented, it may have some characteristics affected by its lifetime, such as its size or transparency. For example, the older the particle, the sooner it will be eliminated from the game, and the smaller its size and transparency.

The emitter is responsible for launching the particles, acting as a point of origin and working in a group with dozens or hundreds of particles simultaneously. Each emitter has several parameters that determine the characteristics of the particles generated by it. These parameters may include, among others:

  • Emission rate of new particles
  • Initial position of the particles
  • Initial speed of the particles
  • Gravity applied to the particles
  • Life time of the particles

When activated, the emitter manages the number of generated particles and can have different behaviors, and can emit a certain number of particles simultaneously and stop (used in an explosion), or constantly emit particles (used in smoke).

It is common for an emitter to allow random value ranges (like the initial position or the lifetime of the particles), creating different and interesting effects each time it is activated, unlike an animation sequence that always exhibits the same effects.

melonJS - a lightweight HTML5 game engine

melonJS (http://melonjs.org/) is an open source engine that uses JavaScript and the HTML5 Canvas element to develop games that can be accessed online via a compatible browser technology. It has native integration with a Tiled Map Editor (http://www.mapeditor.org/), facilitating the creation of game levels. It even has many features such as a basic physics engine and collision management, animations, support for sprite sheets and texture atlases, tweens effects, audio support, a built-in particle system, object pooling, and mouse and touch support among others. All of these features assist in process development and the prototyping of games.

The engine implements a mechanism of inheritance (based on John Resig's Simple Inheritance) allowing any object to be extended. Several functions and classes are provided to the developer for direct use or for extending new features.

The following is a simple example of engine use with an object of type me.Renderable (engine base class to draw on the canvas):

game.myRenderable = me.Renderable.extend({

// constructor
init : function() {
// set the object screen position (x, y) = (100, 200); width = 150 and height = 50
this.parent(new me.Vector2d(100, 200), 150, 50);

// set the z-order
this.z = 1;
},

// logic - collision, movement, etc
update : function(dt) {
return false;
},

// draw - canvas

draw : function(context) {

// change the canvas context color
context.fillStyle = '#000';

// draw a simple rectangle in the canvas
context.fillRect(this.pos.x, this.pos.y, this.width, this.height);
}
});

// create and add the renderable in the game world
me.game.world.addChild(new game.myRenderable());

This example draws a rectangle of dimensions (150, 50) at position (100, 200) of the canvas using the color black (# 000) as filler.

Single particles with melonJS

Using the classes and functions of melonJS, we can assemble a simple particle system, simulating, for example, drops of water. The following example will emit some particles with an initial velocity vertical (Y axis) and will fall until they leave the screen area of ​​the game, through gravity mechanism implemented by the physics engine.

The example can be accessed online (http://aaschmitz.github.io/melonjs-simple-particles) and the code is available on GitHub (https://github.com/aaschmitz/melonjs-simple-particles).

Description: particles-simple.png

Simple particle example

 

The particles will be implemented through a me.Renderable object to draw an image on the canvas, with attributes initialized randomly, allowing that a particle is distinct from another:

game.dropletParticle = me.SpriteObject.extend({

init: function(x, y) {

// class constructor

this.parent(x, y, me.loader.getImage("droplet"));

// the particle update even off screen

this.alwaysUpdate = true;

// calculate random launch angle - convert degrees in radians

var launch = Number.prototype.degToRad(Number.prototype.random(10, 80));

// calculate random distance from point x original

var distance = Number.prototype.random(3, 5);

// calculate random altitude from point y original

var altitude = Number.prototype.random(10, 12);

// particle screen side (value negative is left, positive is right and zero is center)

var screenSide = Number.prototype.random(-1, 1);

// create new vector and set initial particle velocity

this.vel = new me.Vector2d(Math.sin(launch) * distance * screenSide, -Math.cos(launch) * altitude);

// set the default engine gravity

me.sys.gravity = 0.3;

},

update: function(dt) {

// check the particle position in screen limits

if ((this.pos.y > 0) && (this.pos.y < me.game.viewport.getHeight()) &&

(this.pos.x > 0) && (this.pos.x < me.game.viewport.getWidth())) {

// set particle position

this.vel.y += me.sys.gravity;

this.pos.x += this.vel.x;

        this.pos.y += this.vel.y;                  

            this.parent(dt);

            return true;

        } else {

            // particle off screen - remove the same!

            me.game.world.removeChild(this, true);

             return false;

        }

    }

});

 This code snippet is used as a particle, and the class game.dropletParticle must be initialized with the position (x, y) of the particle on the screen. When the particle is not in the visible area of ​​the screen, it will be deleted.

For various particles, we will use a basic emitter, which will be implemented with a normal JavaScript function:

game.startEmitter = function(x, y, count) {

    // add count particles in the game, all at once!

    for (var i = 0; i < count; i++)

        // add the particle in the game, using the mouse coordinates and z-order = 5

        // use the object pool for better performance!

        me.game.world.addChild(me.pool.pull("droplet", x, y), 5);

};

This emitter will be called to emit count particles at once using the initial position (x, y). Note that for best performance, the pooling mechanism of the engine is used in the generation of particles.

Similar to the example described previously, you'll find the implementation effects of drops and stars in an educational game, Vibrant Recyclin. It is available online (http://vibrantrecycling.ciangames.com) and developed by the author using the engine melonJS:

Description: vibrant-recycling.png

Single particles in the game Vibrant Recycling

Improved particles through the embedded particle system

For the use of particles with more advanced or complex effects, the previous example proves to be poor, requiring the addition of more attributes in the particles (such as rotation, lifetime, and so on) and creating a more robust emitter with many different behaviors.

Starting from version 1.0.0 of the melonJS engine, a particle system was added in it, facilitating the creation of advanced particles and emitters. The particle system consists of the following classes:

me.Particle: This is thebase class of particles, responsible for movement (using physics), updating the properties and the drawing of each individual particle. Its properties are set and adjusted directly by the associate emitter.

me.ParticleEmitter: This is theclass responsible for generating the particles according to the parameters configured on each emitter. It can emit particles with a stream behavior (throws particles sequentially in an infinite form or to a defined time) or burst (launches all particles at the same time). For more information, see the official documentation of the engine, available online at http://melonjs.github.io/docs/me.ParticleEmitter.html.

me.ParticleContainer: This is theclass associated with each emitter, which maintains a relationship with all particles generated by it, updating the logic of them and being responsible for the removal of particles that are outside the viewport or have a life time reset.

me.ParticleEmitterSettings: This is the object containing the default settings to be used in emitters, allowing you to create many reusable emitters models. Check the parameters allowed by consulting the official documentation of the engine available online at http://melonjs.github.io/docs/me.ParticleEmitterSettings.html.

To use the particle system with melonJS, do the following:

  • Instantiate an emitter.
  • Adjust the properties of the emitter or assign a me.ParticleEmitterSettings previously created for the same.
  • Add the emitter and its container in the game.
  • Enable the emitter through the functions burstParticles() or streamParticles() however many times necessary.
  • At the end of the process, remove the emitter and its container from the game.

    The following is a basic example of an emitter that, if enabled, will simulate an explosion launching the particles upwards. Note that the example uses a normal JavaScript function and each time the function is called, the emitter is created, activated, and destroyed, which is not a good option if the function is executed several times:

    game.makeExplosion = function(x, y) {

        // create a basic emitter at position (x, y) using sprite "explosion"

        var emitter = new me.ParticleEmitter(x, y, me.loader.getImage("explosion"));

        // adjust the emitter properties

        // launch 50 particles         

        emitter.totalParticles = 50;

        // particles lifetime between 1s and 3s

        emitter.minLife = 1000;

        emitter.maxLife = 3000;

        // particles have initial velocity between 7 and 13

        emitter.speed = 10;

        emitter.speedVariation = 3;

        // initial launch angle between 70 and 110 degrees

        emitter.angle = Number.prototype.degToRad(90);

        emitter.angleVariation = Number.prototype.degToRad(20);

        // gravity 0.3 and z-order 10

        emitter.gravity = 0.3;

        emitter.z = 10;

        // add the emitter to the game world

        me.game.world.addChild(emitter);

        me.game.world.addChild(emitter.container);

        // launch all particles one time and stop

        emitter.burstParticles();

        // remove emitter from the game world

        me.game.world.removeChild(emitter);

        me.game.world.removeChild(emitter.container);

    };

    The example with simple particles described in the previous section will be implemented using the built-in particle system in the engine. This can be accessed online (http://aaschmitz.github.io/melonjs-improved-particles) and the code is available on GitHub (https://github.com/aaschmitz/melonjs-improved-particles).

     game.explosionManager = Object.extend({         

        init: function(x, y) {

            // create a new emitter

            this.emitter = new me.ParticleEmitter(x, y);

            this.emitter.z = 10;

            // start the emitter with pre-defined params

            this.start(x, y);

            // add the emitter to game

            me.game.world.addChild(this.emitter);

            me.game.world.addChild(this.emitter.container);

        },

        start: function(x, y) {

            // set the emitter params

            this.emitter.image = me.loader.getImage("droplet");

            this.emitter.totalParticles = 20;

            this.emitter.minLife = 2000;

            this.emitter.maxLife = 5000;

            this.emitter.speed = 10;

            this.emitter.speedVariation = 3;

            this.emitter.angle = Number.prototype.degToRad(90);

            this.emitter.angleVariation = Number.prototype.degToRad(20);

            this.emitter.minStartScale = 0.6;

            this.emitter.maxStartScale = 1.0;

            this.emitter.gravity = 0.3;

            // move the emitter

            this.emitter.pos.set(x, y);

        },

        launch: function(x, y) {           

            // move the emitter

            this.emitter.pos.set(x, y);

            // launch the particles!

            this.emitter.burstParticles();

        },

        remove: function() {

            // remove the emitter from game        

            me.game.world.removeChild(this.emitter.container);

            me.game.world.removeChild(this.emitter);

        }

    });

    Comparing the examples using simple particles and the one using the built-in particle system of the engine, we note that the second option is more robust, customizable, and fluid. It provides more realism and refinement in the effects created by the particles.

    Description: particles-embedded.png

    Improved particle example using the built-in particle system

    Visual particles editor

    The melonJS engine has a visual particles editor, available online (http://melonjs.github.io/examples/particles/) for creating emitters faster or to make fine adjustments in emitters already created.

    Description: particles-editor

    melonJS particles editor

    The particles editor has a selection menu on the top of screen, where you choose between several emitters preset such as fire, smoke, and rain. The right pane of the screen is responsible for configuring (and tuning) emitters. The left pane displays the configuration parameters of the emitter currently running, serving to be added via code the parameters of the emitter to be used in the game. You can operate the mouse on the center screen indicators (colored circles) affecting directly some properties of the emitters in a visual way.

    Conclusion

    The use of a particle system allows the creation of more enjoyable and interesting visual effects, through customization and randomization of several parameters configured in the emitters, thus creating a greater diversity of particles generated. The melonJS engine proves to be a robust and viable alternative to creating games in HTML5. Being an open source project and having a very active team and community, melonJS receives several enhancements and features with each new version, making it easier for game developers to use.

    About the author

     Andre Antonio Schmitz is a game developer focusing on HTML5 at Cian Games (http://www.ciangames.com). Living in Caxias do Sul, Brasil, he graduated with a Bachelor's degree in Computer Science and an MBA specialization in IT Management. You can find him on Twitter (https://twitter.com/aaaschmitz), Google+ (https://plus.google.com/+AndreAntonioSchmitz/), or GitHub (https://github.com/aaschmitz).

Get your free eBook today

Continue on your journey as a game developer by deciding which game engine and language suits you best with the help of our free eBook.