19 min read

(For more resources related to this topic, see here.)

Introducing particle effects

Particle effects are the decorative flourishes used in games to represent dynamic
and complex phenomena, such as fire, smoke, and rain. To create a particle effect,
it requires three elements: a System, Emitters, and the Particles themselves.

Understanding particle systems

Particle systems are the universe in which the particles and emitters live. Much like
the universe, we cannot define the size but we can define a point of origin which all
emitters and particles will be placed relative to. We can also have multiple particle
systems in existence at any given time, which can be set to draw the particles at
different depths. While we can have as many particle systems as we want, it is best
to have as few as possible in order to prevent possible memory leaks. The reason for
this is that once a particle system is created, it will remain in existence forever unless
it is manually destroyed. Destroying the instance that spawned it or changing rooms
will not remove the system, so make sure it is removed when it is no longer needed.
By destroying a particle system, it will remove all the emitters and particles in that
system along with it.

Utilizing particle emitters

Particle emitters are defined areas within a system from which particles will spawn.
There are two types of emitters to choose from: Burst emitters that spawn particles a
single time, and Stream emitters that spew particles continuously over time. We can
define the size and shape of the region in space for each emitter, as well as how the
particles should be distributed within the region.

Image

When defining the region in space, there are four Shape options: DIAMOND,
ELLIPSE, LINE, and RECTANGLE. An example of each can be seen in the preceding
diagram, all using exactly the same dimensions, amount of particles, and distribution.
While there is no functional difference between using any one of these shapes, the
effect itself can benefit from a properly chosen shape. For example, only a LINE can
make an effect appear to be angled 30 degrees.

Image

The distribution of the particles can also affect how the particles are expelled from
the emitter. As can be seen in the preceding diagram, there are three different
distributions. LINEAR will spawn particles with an equal random distribution
throughout the emitter region. GAUSSIAN will spawn particles more towards the
center of the region. INVGAUSSIAN is the inverse of GAUSSIAN, wherein the
particles will spawn closer to the edges of the emitter.

Applying particles

Particles are the graphic resources that are spawned from the emitters. There are two
types of particles that can be created: Shapes and Sprites. Shapes are the collection of
64 x 64 pixel sprites that comes built-in with GameMaker: Studio for use as particles.
The shapes, as seen in the next diagram, are suitable for the majority of the most
common effects, such as fireworks and flames. When wanting to create something
more specialized for a game, we can use any Sprite in the Resource tree.

Image

There are a lot of things we can do with particles by adjusting the many attributes
available. We can define ranges for how long it lives, the color it should be, and how
it moves. We can even spawn more particles at the point of death for each particle.
There are, however, some things that we cannot do. In order to keep the graphics
processing costs low, there is no ability to manipulate individual particles within an
effect. Also, particles cannot interact with objects in any way, so there is no way to
know if a particle has collided with an instance in the world. If we need this kind of
control, we need to build objects instead.

Designing the look of a particle event is generally a trial and error
process that can take a very long time. To speed things up, try
using one of the many particle effect generators available on the
Internet, such as Particle Designer 2.5 by Alert Games found here:
http://alertgames.net/index.php?page=s/pd2.

HTML5 limitations

Using particle effects can really improve the visual quality of a game, but when
developing a game intended to be played in a browser we need to be careful. Before
implementing a particle effect, it is important to understand potential problems
we may encounter. The biggest issue surrounding particles is that in order for
them to be rendered smoothly without any lag, they need to be rendered with the
graphics processor instead of the main CPU. Most browsers allow this to happen
through a JavaScript API called WebGL. It is not, however, an HTML5 standard
and Microsoft has stated that they have no plans for Internet Explorer to support it
for the foreseeable future. This means a potentially significant portion of the game’s
potential audience could suffer poor gameplay if particles are used. Additionally,
even with WebGL enabled, the functionality for particles to have additive blending
and advanced color blending cannot be used, as none of the browsers currently
support this feature. Now that we know this we are ready to make some effects!

Adding particle effects to the game

We are going to build a few different particle effects to demonstrate the various ways
effects can be implemented in a game, and to look into some of the issues that might
arise. To keep things straightforward, all of the effects we create will be a part of a
single, global particle system. We will use both types of emitters, and utilize both
shape and sprite-based particles. We will start with a Dust Cloud that will be seen
anytime a Pillar is broken or destroyed. We will then add a system to create a unique
shrapnel effect for each Pillar type. Finally, we will create some fire and smoke
effects for the TNT explosion to demonstrate moving emitters.

Creating a Dust Cloud

The first effect we are going to create is a simple Dust Cloud. It will burst outwards
upon the destruction of each Pillar and dissolve away over time. As this effect will be
used in every level of the game, we will make all of its elements global, so they only
need to be declared once.

  1. Open the Tower Toppling project we were previously working on if it is not
    already open.

  2. We need to make sure that WebGL is enabled when we build the game.
    Navigate to Resources | Change Global Game Settings and click on the
    HTML5 tab.

  3. On the left-hand side, click on the tab for Graphics. As seen in the following
    screenshot, there are three options under WebGL in Options. If WebGL is
    Disabled, the game will not be able to use the GPU and all browsers will
    suffer from any potential lag. If WebGL is Required, any browser that does
    not have this capability will be prevented from running the game. The final
    option is Auto-Detect which will use WebGL if the browser supports it, but
    will allow all browsers to play the game no matter what. Select Auto-Detect
    and then click on OK.

    Image

  4. Now that we have WebGL activated we can build our effects. We will start
    by defining our particle system as a global variable by creating a new script
    called scr_Global_Particles.

    code

  5. The first effect we are going to make is the Dust Cloud which will be attached
    to the Pillars. For this we only need a single emitter which we will move to
    the appropriate position when it is needed. Create a global variable for the
    emitter and add it to the particle system with the following code at the end of
    the script:

    code

  6. For this particle, we are going to use one of the built-in shapes,
    pt_shape_explosion, which looks like a little thick cloud of dust.
    Add the following code to the end of the script:

    code

    Once again we have made this a global variable, so that we have to create
    this Dust Cloud particle only once. We have declared only the shape attribute
    of this particle at this time. We will add more to this later once we can see
    what the effect looks like in the game.

  7. We need to initialize the particle system with the other global variables.
    Reopen scr_Global_GameStart and call the particles script.

    code

  8. With everything initialized, we can now create a new script,
    scr_Particles_DustCloud, which we can use to set the region
    of the emitter and have it activate a burst of particles.

    code

    We start by defining a small area for the emitter based on the position of
    instance that calls this script. The region itself will be circular with a Gaussian
    distribution so that the particles shoot out from the center. We then activate a
    single burst of 10 dust particles from the emitter.

  9. All we need to do now is execute this script from the destruction of a Pillar.
    Reopen scr_Pillar_Destroyand insert the following line of code on the
    line before the instance is destroyed:

    code

  10. We need to add this effect to the breaking of the Pillars as well. Reopen scr_
    Pillar_BreakApart
    and insert the same code in the same spot.

  11. Save the game and then play it. When the glass Pillars are destroyed, we
    should see thick white clouds appearing as shown in the following screenshot:

    Image

  12. The particles are boring and static at this point, because we have not
    told the particles to do anything other than to look like the shape of
    a cloud. Let’s fix this by adding some attributes to the particle. Reopen
    scr_Global_Particles and add the following code at the end of the script:

    code

    The first attribute we add is how long we want the particle to live for, which
    is a range between 15 and 30 steps, or at the speed of our rooms, a half to
    a whole second. Next, we want the particles to explode outwards, so we
    set the angle and add some velocity. Both functions that we are using have
    similar parameters. The first value is the particle type for which this is to be
    applied. The next two parameters are the minimum and maximum values
    from which a number will be randomly chosen. The fourth parameter sets
    an incremental value every step. Finally, the last parameter is a wiggle value
    that will randomly be applied throughout the particle’s lifetime. For the Dust
    Cloud, we are setting the direction to be in any angle and the speed is fairly
    slow, ranging only a few pixels per step. We also want to change the size of
    the particles and their transparency, so that the dust appears to dissipate.

  13. Save the game and run it again. This time the effect appears much more
    natural, with the clouds exploding outwards, growing slightly larger, and
    fading out. It should look something like the next screenshot. The Dust
    Cloud is now complete.

    Image

Adding in Shrapnel

The Dust Cloud effect helps the Pillar destruction appear more believable, but it
lacks the bigger chunks of material one would expect to see. We want some Shrapnel
of various shapes and sizes to explode outwards for each of the different types of
Pillars. We will start with the Glass particles.

  1. Create a new Sprite, spr_Particle_Glass, and with Remove Background
    checked, load Chapter 8/Sprites/Particle_Glass.gif.mhanaje This sprite is not
    meant to be animated, though it does have several frames within it. Each
    frame represents a different shape of particle that will be randomly chosen
    when the particle is spawned.

  2. We will want the particles to rotate as they move outwards, so we need to
    center the origin. Click on OK.

  3. Reopen scr_Global_Particles and initialize the Glass particle at the end of
    the script.

    code

    Once we have created the global variable and the particle, we set the particle
    type to be a Sprite. When assigning Sprites there are a few extra parameters
    beyond which resources should be used. The third and fourth parameters are
    for whether it should be animated, and if so, should the animation stretch for
    the duration of the particle’s life. In our case we are not using animation, so it
    has been set to false. The last parameter is for whether we want it to choose
    a random subimage of the Sprite, which is what we do want it to do.

  4. We also need to add some attributes to this particle for life and movement.
    Add the following code at the end of the script:

    code

    When compared with the Dust Cloud, this particle will have a shorter
    lifespan but will move at a much higher velocity. This will make this effect
    more intense while keeping the general area small. We have also added some
    rotational movement through part_type_orientation. The particles can
    be set to any angle and will rotate 20 degrees per frame with a variance of up
    to four degrees. This will give us a nice variety in the spin of each particle.
    There is one additional parameter for orientation, which is whether the angle
    should be relative to its movement. We have set it to false as we just want
    the particles to spin freely.

  5. To test this effect out, open up scr_Particles_DustCloud and insert a burst
    emitter before the Dust Cloud is emitted, so that the Glass particles appear
    behind the other effect.

    code

  6. Save the game and then play it. When the Pillars break apart, there should be
    shards of Glass exploding out along with the Dust Cloud. The effect should
    look something like the following screenshot:

    Image

  7. Next we need to create Shrapnel for the Wood and Steel particles. Create new
    Sprites for spr_Particle_Wood and spr_Particle_Steel with the supplied
    images in Chapter 8/Sprites/ in the same manner as we did for Glass.

  8. As these particles are global, we cannot just swap the Sprite out dynamically.
    We need to create new particles for each type. In scr_Global_Particles,
    add particles for both Wood and Steel with the same attributes as Glass.

  9. Currently the effect is set to Always create Glass particles, something we
    do not want to do. To fix this we are going to add a variable, myParticle,
    to each of the different Pillars to allow us to spawn the appropriate particle.
    Open scr_Pillar_Glass_Create and add the following code at the end of
    the script:

    code

  10. Repeat the last step for Wood and Steel with the appropriate particle assigned.

  11. In order to have the proper particle spawn, all we need to do is reopen
    scr_Particles_DustCloud and change the variable particle_Glass to
    myParticle as in the following code:

    code

  12. Save the game and play the game until you can destroy all the three types
    of Pillars to see the effect. It should look something similar to the following
    screenshot, where each Pillar spawns its own Shrapnel:

    Image

Making the TNT explosion

When the TNT explodes, it shoots out some TNT Fragments which are currently
bland looking Sprites. We want the Fragments to be on fire as they streak across the
scene. We also want a cloud of smoke to rise up from the explosion to indicate that
the explosion we see is actually on fire. This is going to cause some complications.
In order to make something appear to be on fire, it will need to change color, say
from white to yellow to orange. As we have already mentioned, due to the fact that
WebGL is not supported by all browsers, we cannot utilize any of the functions that
allow us to blend colors together. This means that we need to work around this issue.
The solution is to use several particles instead of one.

  1. We will start by creating some custom colors so that we can achieve the look
    of fire and smoke that we want. Open scr_Global_Colors and add the
    following colors:

    code

    We already have a nice yellow color, so we add an orange, a slightly yellow
    tinted white, and a partially orange black color.

  2. In order to achieve the fake blending effect we will need to spawn one
    particle type, and upon its death, have it spawn the next particle type. For
    this to work properly, we need to construct the creation of the particles in
    the opposite order that they will be seen. In this case, we need to start by
    building the smoke particle. In scr_Global_Particles add a new particle
    for the smoke with the following attributes:

    code

    We start by adding the particle and using the built-in smoke shape. We want
    the smoke to linger for a while, so we set its life to range between a minimum
    of a second to almost two full seconds. We then set the direction and speed
    to be more or less upwards so that the smoke rises. Next, we set the size and
    have it grow over time. With the alpha values, we don’t want the smoke to
    be completely opaque, so we set it to start at half transparent and fade away
    over time. Next, we are using part_type_color1 which allows us to tint the
    particle without affecting the performance very much. Finally, we apply some
    gravity to the particles so that any angled particles float slowly upwards.

  3. The smoke is the final step of our effect and it will be spawned from an
    orange flame that precedes it.

    code

    Once again we set up the particle using the built-in smoke shape, this time
    with a much shorter lifespan. The general direction is still mainly upwards,
    though there is more spread than the smoke. These particles are slightly
    smaller, tinted orange and will be partially transparent for its entire life. We
    have added a little bit of upward gravity, as this particle is in between fire
    and smoke. Finally, we are using a function that will spawn a single particle
    of smoke upon the death of each orange particle.

  4. The next particle in the chain for this effect is a yellow particle. This time we
    are going to use the FLARE shape, which will give a better appearance of fire.
    It will also be a bit smaller, live slightly longer than the orange particle, and
    move faster, spreading in all directions. We will not add any transparency to
    this particle so that it appears to burn bright.

    code

  5. We have only one more particle to create this effect for, which is the hottest
    and brightest white particle. Its construction is the same as the yellow
    particle, except it is smaller and faster.

    code

  6. We now have all the particles we need for this particle effect; we just need
    to add an emitter to spawn them. This time we are going to use a stream
    emitter, so that the fire continuously flows out of each Fragment. Since
    the Fragments are moving, we will need to have a unique emitter for each
    Fragment we create. This means it cannot be a global emitter, but rather a
    local one. Open scr_TNT_Fragment_Create and add the following code at
    the end of the script:

    code

    We create an emitter with a fairly small area for spawning with balanced
    distribution. At every step, the emitter will create five new Fire particles as
    long as the emitter exists.

  7. The emitter is now created at the same time as the Fragment, but we need the
    emitter to move along with it. Open scr_TNT_Fragment_Step and add the
    following code:

    code

  8. As already mentioned we need to destroy the emitter, otherwise it will never
    stop streaming particles. For this we will need to open obj_TNT_Fragment
    and add a destroy event with a new Script, scr_TNT_Fragment_Destroy,
    which removes the emitter attached.

    code

    This function will remove the emitter from the system without removing any
    of the particles that had been spawned.

  9. One last thing we need to do is to uncheck the Visible checkbox, as we don’t
    want to see the Fragment sprite, but just the particles.

  10. Save the game and detonate the TNT. Instead of just seeing a few
    Fragments, there are now streaks of fire jetting out of the explosion
    that turn into dark clouds of smoke that float up. It should look
    something like the following screenshot:

    Image

Cleaning up the particles

At this point, we have built a good variety of effects using various particles and
emitters. The effects have added a lot of polish to the game, but there is a flaw with
the particles. If the player decides to restart the room or go to the SHOP immediately
after the explosion has occurred, the emitters will not be destroyed. This means that
they will continue to spawn particles forever, and we will lose all references to those
emitters. The game will end up looking like the following screenshot:

Image

  1. The first thing we need to do is to destroy the emitters when we leave
    the room. Luckily, we have already written a script that does exactly
    this. Open obj_TNT_Fragment and add a Room End event and attach
    scr_TNT_Fragment_Destroy to it.

  2. Even if we destroy the emitters before changing rooms, any particles
    remaining in the game will still appear in the next room, if only briefly.
    What we need to do is clear all the particles from the system. While this
    might sound like it could be a lot of work, it is actually quite simple. As
    Overlord is in every level, but not in any other room, we can use it to clean
    up the scene. Open obj_Overlord, add a Room End event and attach a
    new Script, scr_Overlord_RoomEnd, with the following line of code:
    part_particles_clear(system);

    This function will remove any particle that exists within the system, but will
    not remove the particle type from memory. It is important that we do not
    destroy the particle type, as we would not be able to use a particle again if
    its type no longer exists.

  3. Save the game, explode some TNT, and restart the room immediately. You
    should no longer see any particles in the scene.

Summary

In this article, we were provided with the details to add some spit and polish to the game to really make it shine. We delved into the world of particles and created a variety of effects that add impact to the TNT and Pillar destruction.

Resources for Article :


Further resources on this subject:



Subscribe to the weekly Packt Hub newsletter

* indicates required

LEAVE A REPLY

Please enter your comment!
Please enter your name here