In this article, we’ll begin with the basics of the GameMaker Studio particle system and end with advanced techniques and implementations. Think of this as a crash course to get you familiar and comfortable with one of GameMaker Studio’s most powerful built-in features. The demo and downloadable project file will allow you to follow along with the article to see exactly what the particle system is all about.
Particle System Overview
The GameMaker Studio particle system is a cheap and easy way to create flashy effects for your game project. Through a combination of particles and emitters, you can quickly create impressive explosions, smoke, blood, shrapnel, and countless other effects. Similar effects can be achieved by using individual objects, but the computing cost of the built-in particle effects system is far cheaper.
To use the particle system in your project, you'll need to understand GML (GameMaker Language), but once you become familiar with the particle system, it is simply a matter of filling in the blanks and experimentation.
Check out the demo below to see what we can achieve:
Particle System Basics
Particle Systems in GameMaker Studio consist of three parts: the system itself, the particle, and the emitter. You can create multiple systems, and each system can contain multiple particles and emitters. Think of the system as a container, with the particles and the emitters defined within.
Implementing a particle effect in GameMaker Studio is a four step process.
- First, you must define the particle system itself.
- Then, you define the actual particles that will be used within that system.
- Next, you have to define the emitter that will create your defined particles.
- Finally, you have to determine when and where the particle emitter will appear in your game.
To teach you the basics of the GameMaker Studio particle system, we’ll start out by creating this very simple green particle effect.
Creating the Particle System
Creating the particle system is
as simple as defining a variable. We create an object called obj_first_particle
and place the following code in the object’s Create event:
FirstParticleSystem = part_system_create();
The particle system will adopt the depth value of the object that the system is defined in, but you can also set the depth separately with GML:
part_system_depth(FirstParticleSystem,0);
Remember that objects and
particle systems with a high depth value are drawn to the screen first. With a
depth of 0
, our green particle system will appear above objects with a depth
greater than 0
, and will appear below objects with a depth less than 0
.
Particle systems are drawn to the
screen with a base position relative to (0,0)
. If for some reason you want to
create an offset for all future positions of this particle system, you can use
the following code to create a new base position (where ind
is the particle
system):
part_system_position(ind, x, y);
With a new base position set to(10,10)
, a particle created at (25,25)
will instead be drawn to (35,35)
.
Changing the base position of a particle system is rarely necessary, but you
may find it useful in your specific project.
Creating the Particle Type
Now that the system has been set
up, it is time to define the actual particle that the emitter will create.
Particles can contain a large number of parameters that dictate how the particle
will look and behave. The first step is to create a variable for the particle,
and we do this in the Create
event of the obj_first_particle
object:
first_particle = part_type_create();
Next, we begin defining the
individual parameters of the particle. Since we do not plan on altering this
particle during runtime, we can place all of this code in the Create
event of
the obj_first_particle
object.
part_type_shape
determines the
base shape of the particle. There are 14 default particle shapes available in
GameMaker Studio, and you can define your own shapes as well. We’ll cover this
in the advanced section below, but for now let’s just start with a basic
square.
part_type_shape(first_particle,pt_shape_square);
For a full list of the available default shapes, check the official GameMaker documentation.
With part_type_scale
, we can set
the base X and Y scale values of the particle shape. Since we want a perfect
square shape, we use the following code:
part_type_scale(first_particle,1,1);
part_type_size
allows us to alter
the size of the particle at creation and as well as over time. The format for
this code is part_type_size(ind, size_min, size_max, size_incr, size_wiggle)
.
ind
is the particle variable.size_min
andsize_max
determine the range of the particle size when it is first created. If you want a uniform size, simply enter the same value for both the min and the max.size_incr
is a value that allows the particle to grow or shrink over time. This value determines the speed of growth, so if you don’t want your sprite to change size, you can use a value of0
.size_wiggle
is slightly more complicated, so we’ll cover that in the advanced techniques section below.
Here’s the particle size code used in our green particle effect:
part_type_size(first_particle,0.10,0.15,-.001,0);
The particle will be created with
a size somewhere between 0.10
and 0.15
to create variety, and the sprite will
slowly shrink at a speed of -0.001
. This speed value depends greatly on your
room speed, so you will likely need to experiment with values to get the
desired results. We will not be using any size wiggle, so we set the value to0
.
Particles in GameMaker Studio can
actually change colors over time. This is achieved with part_type_color2
andpart_type_color3
. If you don’t want your sprite to change colors, then you can
just use part_type_color1
. For our green particle effect, we want it to start
out with a bright yellow/green color and then change to a solid green color, so
we use part_type_color2
:
part_type_color2(first_particle,8454143,65280);
The two colors I selected are
specific numerical values that I use regularly, but if you want to use more
traditional hex values, you can use the format $RRGGBB
.
Particles can also become more or
less transparent over time with part_type_alpha2
and part_type_alpha3
. If you
want a consistent alpha value, use part_type_alpha1
. For our green particle
effect, we want the particle to start completely opaque and fade by 25% as it stays on the screen, so we need two alpha values:
part_type_alpha2(first_particle,1,0.75);
In GameMaker, alpha is a value from 0 to 1. A completely invisible object will have an alpha value of 0, while a completely opaque object will have an alpha value of 1.
Particle speed is determined just
like particle size. Particles are created within a range of speed values, and that
value can increase or decrease. The format for this code is part_type_speed(ind,
speed_min, speed_max, speed_incr, speed_wiggle)
, where ind
is the particle
variable, speed_min
and speed_max
is the speed range, speed_incr
is the rate at
which the particle speed changes, and speed_wiggle
is a parameter that we’ll
cover later on.
The speed code for our green particle is:
part_type_speed(first_particle,0.1,0.5,0,0);
Our particle will start moving
with a speed value somewhere between 0.1
and 0.5
. This speed will remain
constant, so we use a value of 0
, and we will again not be implementing speed wiggle,
so we use a value of 0
.
While a particle’s speed parameter
determines how fast it moves, the direction parameter determines where it moves.
The direction code is in the following format: part_type_direction(ind,
dir_min, dir_max, dir_incr, dir_wiggle)
and again we set the variable, starting
range, an incremental value, and a wiggle value. For the green particle effect,
we want our particle to start moving in any direction, and we want that
direction to remain constant:
part_type_direction(first_particle,0,359,0,0);
The range of 0 to 359 ensures that the particle has a chance to move in any direction (an angle between 0 and 359 degrees). If you wanted a particle to move up and only up, then you would use a range of 90 to 90).
The gravity of our particle
effect is what makes it the most interesting. While our speed and direction
parameters are set to create a particle that starts by moving in one direction at a
constant speed, the gravity parameter kicks in and alters the particle over
time. With a format of part_type_gravity(ind, grav_amount, grav_direction)
, the
gravity parameter is very simple:
part_type_gravity(first_particle,0.02,90);
By applying a slight gravitational pull of 0.02 in an upward direction (90 degrees), we can create a particle that appears to float. Combined with our size and alpha parameters, the particle shrinks and becomes more transparent over time, accompanied by the gravitational lift.
The orientation of the particle
shape is also important to the appearance of the effect, so we use part_type_orientation(ind, ang_min, ang_max, ang_incr, ang_wiggle, ang_relative)
to rotate the
square over time.
ind
is the particle variable.ang_min
andang_max
determine the starting value of the shape’s rotation value.ang_incr
is used to increment or decrement the shape’s orientation over time.ang_relative
is a Boolean value to determine if the orientation should be set relative to the motion of the particle (true) or not (false).
We want our green particle to rotate slightly to the left, so we use the following code:
part_type_orientation(first_particle,0,359,10,0,true);
One of the most important parameters of a particle is the lifespan value. This value determines the minimum and maximum time that a particle will be drawn to the screen. With two identical min and max values, all particles of that type will exist for the same amount of time. We want our green particles to have variety, so we will use a range of 100 to 150 for the lifespan value:
part_type_life(first_particle,100,150);
The final parameter for particles is a simple Boolean to determine whether the particles should blend together with an additive blend effect:
part_type_blend(first_particle,true);
Creating the Particle Emitter
The first step in defining an
emitter is to create a variable. We define this emitter in the Create event of
the obj_first_particle
object.
first_emitter = part_emitter_create(FirstParticleSystem);
Next, we define the emitter
region with part_emitter_region(ps, ind, xmin, xmax, ymin, ymax, shape,
distribution)
.
ps
is the particle system that the emitter belongs to andind
is the emitter variable.- The x and y min and max values determine the size of the emitter region.
shape
determines the shape of the emitter region (ps_shape_rectangle, ps_shape_ellipse, ps_shape_diamond, ps_shap_line
).distribution
is a distribution curve (ps_dist_linear, ps_distr_gaussian, ps_distr_invgaussian
).
We’ll cover the shape and distribution parameters in further detail in the advanced techniques section. For now, we’ll use the default ellipse shape and Gaussian distribution values:
part_emitter_region(FirstParticleSystem, first_emitter, x-20, x+20, y-20, y+20, ps_shape_ellipse, ps_distr_gaussian);
This code creates an elliptical emitter
region that is 40 pixels tall and 40 pixels wide, and centred on the x and y values
of the obj_first_particle
object. Particles created by the emitter will appear
within this defined region.
Activating the Particle Emitter
The next step is to determine one of two emitter types: Burst or Stream. A Burst emitter creates a specified amount of a certain particle whenever it is triggered. A Stream emitter creates a specified amount of a certain particle once every step.
We’ll take a look at the more versatile Burst emitters in the advanced techniques section, so for now let’s just use the Stream emitter:
part_emitter_stream(FirstParticleSystem,first_emitter,first_particle,1);
We place this code in the Create
event of the obj_first_particle
object, resulting in the emitter creating one particle each step as soon as the object is created. With a room speed of 30,
our emitter will create 30 particles per second; to create 60 particles per
second, you would simply use a value of 2
instead of 1
.
And with that, our simple green particle effect is complete! The usefulness of this effect is limited, but it’s important to start small before diving into the more complicated aspects of the GameMaker Studio particle system. Once you understand the basics of the particle system, you can start implementing more advanced particle systems.
Advanced Particle System Techniques
Particle Wiggle
Wiggle is a simple, yet powerful parameter that can drastically change the
appearance of your particles. The wiggle parameter causes the particle to oscillate
between the min and max values for the lifetime of the particle. The value can
be between 0
and 20
and determines the speed of the wiggle.
The "Fire Bubble" example in the embedded demo uses a wiggle value of 0.40
in the part_type_size
parameter:
part_type_size(fire_bubble_part,0.25,0.75,-0.01,0.40);
Burst Emitters and Moving Objects
One of the most common implementations of particle systems involves particles
that emanate from behind a moving object, such as a smoke trail on a rocket. Achieving
this effect in GameMaker Studio requires a Burst emitter to be placed in an
object’s Step
event.
The included example uses the
same green particle system as before, but with a slightly modified emitter. Instead
of triggering a Stream emitter in the object’s Create
event, a Burst emitter is
placed in the object’s Step
event. The current position of the mouse cursor is
checked against the previous position of the cursor, and if there is a change in the
cursor’s position, the Burst emitter is triggered to release five particles:
x = mouse_x; y = mouse_y; part_emitter_region(MouseParticle,green_mouse_emitter,x,x,y,y,0,0); if x != old_x || old_y != y { part_emitter_burst(MouseParticle,green_mouse_emitter,green_mouse_particle,5); } old_x = x; old_y = y;
Emitter Region Shapes
By using the different emitter shapes and distribution curves, you can create vastly different effects. Linear curve distribution combined with a line-shaped particle emitter can create a convincing rain effect.
part_emitter_region(RainParticle, rain_emitter, -100, room_width, y, y, ps_shape_line, ps_distr_linear);
The emitter shape is defined by a
line that begins 100 pixels to the left of the room origin and is extended to
the width of the room. A linear distribution curve is used to distribute the
rain particles evenly across the emitter region. It is also useful to usepart_system_update
to advance the rain particle several steps in the Create
event. This code gives the impression that the rain was falling before you
loaded the room, even though the particle system didn’t exist in memory yet.
repeat (room_speed * 3) { part_system_update(RainParticle); }
Particle System Step and Death Effects
Individual particles within a
system can also spawn other particles on Step
and Death
events. The example shows
a purple spark particle that spawns smaller dust particles as it travels to the
right, and spawns a smoke particle at the end of its lifespan:
part_type_step(spark_particle,1,dust_particle); part_type_death(spark_particle,5,smoke_particle);
Custom Particle Shapes
By using part_type_sprite(ind,
sprite, animate, stretch, random)
, you can use custom sprites instead of the
built-in GameMaker particle types.
ind
is the particle variable.sprite
is the sprite variable to be used.animate
is a Boolean to determine if the sub-images should be animated.stretch
is a Boolean that matches the animation length to the lifespan of the particle.random
is a Boolean to determine whether the starting sub-image should be randomly selected.
part_type_sprite(heart_particle,spr_heart,false,false,false);
Memory Management
The most important thing to remember about the GameMaker Studio particle system is that you need to manually remove items from memory when not in use. Unlike standard game objects, particle systems will remain in memory even if you change rooms. The easiest way to handle this is to place memory management code in the room changing events of your game objects.
part_system_clear(ind)
: Clears all emitters and particles belonging to a specific particle system.part_system_clear(ind)
: Clears all instances of a specific particle type.part_emitter_clear(ps, ind)
: Clears all particles belonging to a specific emitter.part_emitter_destroy(ps, ind)
: Destroys a specific emitter in a specific particle system.part_emitter_destroy_all(ps)
: Destroys all emitters in a specific particle system.part_type_destroy(ind)
: Destroys a specific particle type.part_system_destroy(ind)
: Destroys an entire particle system, including all particles and emitters contained within.
Conclusion
Even with such a lengthy tutorial, we've still only scratched the surface of what kinds of effects the GameMaker Studio particle system is capable of. The key to mastering particles is familiarity and experimentation, so jump in and start creating your own effects using the knowledge you've gained. Be sure to check out the official GameMaker documentation to view all the available particle system GML!