PARTICLES EXPLAINED
IntroductionWhat is a particle?A particle is a graphic resource that has certain properties which are defined by a
particle system. These properties cannot be manipulated directly
for individual particles, but are changed through the code that is used to define the sytem that it belongs to. They are very useful for creating beautiful and flashy effects (or subtle and discreet ones!) in a game without the cpu overhead that using objects has.
What is a particle system?Think of a particle system like a container that we will use to hold our particles ready for use. We use code to define a series of visial aspects for our particle, and then we place it in the "container" so that we can take it out and use it whenever and wherever we need later.
How do I set one up?Well, before setting up a system itīs important to know a few things... First off is that most of a particle systems code is only ever called ONCE in the game, usually in some type of controller object in the first room or level (this is not always the case, but for the sake of simplicity, weīll keep it like this!). This is because a particle system, once created, stays in memory and is ready to be used at any time, so if you create it more than once it can quickly up the memory usage and cause serious lag, before eventually crashing the game... In this example we will make a global particle system that can be used by any object at any time...
Part I - Creating A Particle SystemOkay, to start with we need to define the particle system and give it a name so that we can use it... As this is going to be a global sytem that any object can use we will do it like this...
global.P_System=part_system_create();
Easy, huh? So thatīs the system created, but what about particles? We have to define them too or the sytem is useless and does nothing! To create a particle you have to define itīs general properties. These are like object properties, but they only apply in a general way to individual particles... What this means is that if you give the particles a movement speed of 1,2 any particle created by the system will have a
random speed between 1 and 2 pixels per step, and that overall they will have an average speed of 1.5... Letīs name and add our first particle to the sytem, then...
global.Particle1=part_type_create();
Great, but weīre not ready yet to create our outstanding effects... We have still to define the general properties of our particle (ie: how it looks, itīs speed, rotation, alpha etc...). There are a lot of details that can be put into a particle, so to show them Iīll post what the manual says and include a snippet of code that has them all too...
- part_type_shape(ind, shape) Sets the shape of the particle type to any of the constants above (default is pt_shape_pixel).
- part_type_size(ind, size_min, size_max, size_incr, size_wiggle) Sets the size parameters for the particle type. You specify the minimum starting size, the maximum starting size, the size increase in each step (use a negative number for a decrease in size).
- part_type_scale(ind, xscale, yscale) Sets the horizontal and vertical scale. This factor is multiplied with the size. It is in particular useful when you need to scale differently in x- and y-direction.
- part_type_color1(ind, color1) Indicates a single color to be used for the particle.
- part_type_alpha1(ind, alpha1) Sets a single alpha transparency parameter (0-1) for the particle type.
- part_type_speed(ind, speed_min, speed_max, speed_incr, speed_wiggle) Sets the speed properties for the particle type. You specify a minimal and maximal speed. A random value between the given bounds is chosen when the particle is created. You can indicate a speed increase in each step Use a negative number to slow the particle down (the speed will never become smaller than 0).
- part_type_direction(ind, dir_min, dir_max, dir_incr, dir_wiggle) Sets the direction properties for the particle type. Again you specify a range of directions (in counterclockwise degrees; 0 indicated a motion to the right). For example, to let the particle move in a random direction choose 0 and 360 as values. You can specify an increase in direction for each step.
- part_type_orientation(ind, ang_min, ang_max, ang_incr, ang_wiggle, ang_relative) Sets the orientation angle properties for the particle type. You specify the minimum angle, the maximum angle, the increase in each step and the amount of wiggling in angle. You can also indicate whether the given angle should be relative (1) to the current direction of motion or absolute (0). E.g. by setting all values to 0 but ang_relative to 1, the particle orientation will precisely follow the path of the particle.
- part_type_blend(ind, additive) Sets whether to use additive blending (1) or normal blending (0) for the particle type.
- part_type_life(ind, life_min, life_max) Sets the lifetime bounds for the particle type.
Before you look at the code, Iīll just mention a couple of things...
- When you see "wiggle", that means that if you place a number between 1 and 20 the particle will "wiggle" or fluctuate between the min and max values for the code (with 1 being a slow wiggle and 20 being very fast). So a speed min of 2 and max of 5 and wiggle of 20 will occilate very quickly between the min/max speeds for the lifetime of each particle...
- Lifetime? Thatīs the length of time in steps that a particle will exist for. So, a lifetime of 30,30 will have the particle existsing for exactly 30 steps, but a liftime of 20,60 will have each particle exists for a random number of steps between 20 and 60...
- There are actually 6 different ways to define colour for a particle (you use only one, not all!), but as this is for beginners I havenīt included them. Check the manual as they are easy to understand and offer more flexibility...
- There are also 3 different codes for setting alpha (yes, use only the one thatīs needed, not all!)... Again, check the manual as they are very useful...
- Finally, the blend option. This means that the particle can have additive blending or normal. Whatīs that? Well additive means that itīs brightness will be added to whatever is behind it on the screen, and so gives that saturated glowing look!! Useful for fire and magic effects (for example), but best left off for something like smoke... Experiment to see the differences...
Now to define our global particle using the codes detailed above...
part_type_shape(global.Particle1,pt_shape_pixel) //This defines the particles shape...
part_type_size(global.Particle1,1,1,0,2) //This is for the size...
part_type_scale(global.Particle1,1,1) //This is for scaling...
part_type_color1(global.Particle1,c_white) //This sets itīs colour. There are three different codes for this...
part_type_alpha1(global.Particle1,1) //This is itīs alpha. There are three different codes for this...
part_type_speed(global.Particle1,0.50,2,-0.10,0) //The particles speed...
part_type_direction(global.Particle1,0,359,0,20) //The direction...
part_type_orientation(global.Particle1,0,0,0,0,1) //This changes the rotation of the particle...
part_type_blend(global.Particle1,1) //This is the blend mode, either additive or normal...
part_type_life(global.Particle1,1,20) //this is itīs lifespan in steps...
So thatīs it! We have now defined our particles and they are ready to be used? How do we do that? Read on...
Part II(a) - Creating Particles DirectlyThere are a couple of ways to create particles, and each has itīs pros and cons... You can use emitters to burst or stream particles, or you can creat particles directly at a point. Which one you use really depends on what you are trying to achieve and the effect you are wanting to create. Iīll start with the easiest of the two, which is creating particles directly with part_particles_create...
part_particles_create(global.P_System, x, y, global.Particle1, 50);
Thatīs it? Yup! That short code above will create at the objectīs x/y coords 50 particles of Particle1 from our global system. Easy, huh? The great thing about that line of code is that it can be used
anywhere without any fuss. For example if you place it in the global left pressed event for the mouse in an object and change x/y for mouse_x/y, it will create particles at the mouse position every time you press the button. Or if you have a rocket, then you could place this in the step event and have smoke particles coming every step (although 1 or 2 would probably be better than 50!). You can even have it create particles over an area by changing the x/y coords randomly (eg: "x+20-random(40),y+20-random(40)" will create random particles inside a 40px square...).
Part II(
- Creating Particles With EmittersSince Iīve explained the easy way, Iīll now explain the slightly more complex way, which is to use emitters. Emitters are another part of the particle system that has to be defined before being used, so weīll make a global emitter the same as the system and the particles. We also have to decide whether to have a
static (non-moving) emitter and whether we are going to burst or stream the particles, as well as over what area and what kind of distribution we are going to do it. What does all that mean? Well, a static emitter is one that you can define once and forget about as it will no be moving anywhere. Think of a log fire... It doesnīt move, it just emits flames! But a fireball is a non-static emitter and will move across the screen... As for bursting or streaming, a burst is a one off explaosion of particles, whereas a stream is just that... a constant stream of particles every step. As for area and distribution, with emitters you can define an area for emitting particles (rectangle, ellipse, diamond or line) as well as the distribution curve (gaussian, invgaussian, or linear)... Oh, and
please read the manual on emitters as (as always!) it contains more info and codes that you may need or find useful!
Here is a set of example codes that define two emitters. One will be static and stream particles over the area of the whole room, while the other will follow
the mouse and burst every 30 steps from a small ellipse...
//CREATE EVENT
//Define and name the emitters
global.Particle1_Emitter1=part_emitter_create(global.P_System);
global.Particle1_Emitter2=part_emitter_create(global.P_System);
//Set up the area that will emit particles
part_emitter_region(global.P_System, global.Particle1_Emitter1, 0, room_width, 0, room_height, ps_shape_rectangle, ps_distr_linear);
part_emitter_region(global.P_System, global.Particle1_Emitter2, mouse_x-10, mouse_x+10, mouse_y-10, mouse_y+10, ps_shape_ellipse, ps_distr_gaussian);
//Set the first to stream 10 particles every step
part_emitter_stream(global.P_System, global.Particle1_Emitter1, global.Particle1, 10);
//This can now be forgotten as it will function until told to stop...
//Set the alarm[0] event to burst the emitter2 particles...
alarm[0]=30;
//ALARM[0] EVENT
//The second emitter has to move to the mouse position so...
part_emitter_region(global.P_System, global.Particle1_Emitter2, mouse_x-10, mouse_x+10, mouse_y-10, mouse_y+10, ps_shape_ellipse, ps_distr_gaussian);
//Now to burst 30 particles and reset the alarm[0]
part_emitter_burst(global.P_System, global.Particle1_Emitter2, global.Particle1, 30);
alarm[0]=30;
But what if you want several objects to emit particles? A global emitter can only be in one place at a time, so you would need to create
local emitters in each object. These emitters will still use the global particle system and any particles that are within it, but they can be different shapes and sizes and move with the object, making them ideal for rockets or bullets or things... The code is exactly the same as above, but without the "global." before the emitter names, and you will have to 'clean up' in the destroy event of the object too (see Part III, below). Check out room 2 in the tutorial file for examples of this...
Thatīs the creation of particles dealt with but there is one more thing thatīs very important... Cleaning up when you are finished with them...
Part III - Cleaning UpAs I mentioned at the start, once created, a particle system (and itīs particles, emitters etc...) are stored in memory for instant use. Great, but what
happens when you restart the game? Or if your player dies and starts the room again? Well, if you donīt manage the game right you get a memory leak. This is when something is eating up memory and causes lag or even blocks the computer, and is a pretty common problem with first time users of particle systems. How do you avoid this? Well, GM has a couple of functions to delete particle systems and their emitters and things from memory when not in use and with a little bit of planning and these codes it will cease to be a problem...
The first thing you have to do is decide where you are going to create the system and how you will use it. You could create it in the game start event of an object that is in your first room (a menu or title screen), but this means that if you use the restart game codes it will be recreated and cause a memory leak... To avoid that you would have something like this...
part_type_destroy(global.Particle1);
part_emitter_destroy(global.P_System, global.Particle1_Emitter);
part_system_destroy(global.P_System);
game_restart();
This will remove the particle, the emitter and then the system from memory before restarting the game again. Or if you have it in a controller object that is placed in every game room, then you could have the create event that defines the particle system and things, then place the destroy codes in the room end event...Just remember that after thinking about where would be the most suitable place to create the system, think about where would be the most suitable place to destroy the system too!!! If you check out the file that goes with this tutorial you can see what I mean by looking at the room end and destroy events of the objects used.
SummaryRight, now you know the basics about particles, particle systems and emitters, so off to create a game!!! Not quite... As I said at the start, particles are less cpu hungry than objects, but they are not the solution to everything as they
will cause lag if you have thousands of them at a time. The best thing to do is experiment and use them carefully to "flesh out" visually a game and give it abit more eye-candy without over doing it... Another thing to take into account is that a particle system can be a chore to set up and test, so I canīt recomend enough that you use one of the many particle designing tools that are available on Yoyo. My personal favorite is
Particle Designer 2.3 by Alert Games, as it is very powerful and permits you to export the file as a gml script that can then be imported into any game file... I have also prepared a demo file to acompany this tutorial that you can download here :
http://host-a.net/Ma...r_Beginners.gmkThatīs it for me!!! I hope that this tutorial has helped you, and donīt forget to download the example file as itīs a lot easier to understand when you see everything working together than it may seem by just reading this... and if you still thirst for more, then RhysMeyers has a far more extensive pdf file with just about everything particle related
HERE.
All the best,
Nocturne