***This tutorial is for GameMaker 8.1 and earlier versions. Many of these functions are obsolete in GameMaker:Studio***
Welcome back to another Game Maker tutorial. This time we are going to take a look at Game Maker’s Particle system. If you haven’t played with it yet, it is incredibly robust and can make almost any effect you can imagine. However, before you can do that, you need to understand the underlying functions, and that is what we will focus on.
Game Maker 8.0’s particle system can be a bit confusing at first. There isn’t a lot of documentation or examples of how it needs to be built in order to work effectively. There are also a huge amount of functions available and it can be hard to know where to start. So let’s start at the beginning.
In order to create a particle effect, it needs at a minimum of three elements. First, it needs a System, which is a container for the effect. Second it needs a Particle Type, which is the graphical information of what is to be displayed. Finally, you need an Emitter, which is what spawns the particles. Additionally, Game Maker supplies several other optional elements. There are Attractors, which will push or pull particles near it. Deflectors, which as it sounds, will allow for particles to bounce off of it. Changers are interesting as it allows you to change the particles from one type to another. Last, but not least, are the Destroyers which will remove any particles it touches. I cannot think of any effect that needs any more elements than this.
Now that we know what is going into the effect, we need to know how it needs to be implemented. This most common issue I see from people trying to build effects is that they place all the code into a single script file. While it may appear to work fine, and it follows the description provided in the help menu, it will cause problems such as the effect remaining when it should not. I prefer to keep things separate from each other in three scripts. An Initiating script that contains the creation of all the elements of the effect. An Activated script which contains all the information of how the particles should act and react while the effect is running. A Clean Up script is then used to removed the effect from game, including all the particles themselves.
Rather than me talking about it, why don’t we build a particle effect that utilizes all of these features. In this case, it will be a Water Fountain of sorts.
The goal of this project will be to build a particle system that touches upon every element that Game Maker provides. This project will not, however, delve into each and every function available to you. There is just too many functions and it may ruin your adventure of exploring all of them. So what is it we are building exactly?
- Particle system is only active when space bar is down
- Particles will shoot upwards
- Particles are affected by gravity
- Particles can change direction relative to the mouse
- Particles will bounce on floor
- Particles will change to another type on deflection
- Particles will die if pulled to the left
- Particles system and its element will be removed after use
Work File: ParticleSetup.gmk
I have provided a basic example file, but if you want to build it from scratch, this is what you will need. Start by creating a single object and call it obj_Spout. We will also need to sprites; one for the object which can be a simple box and is just used so you can see the objects placement, and a small sprite that will be used as a particle (call it spr_myParticle). Place the object in the room, preferably in the lower part of the screen in the center. We will also need three scripts: scr_Particle_Init, scr_Particle_Active, scr_Particle_Clean. That’s pretty much it as everything else will be done in code.
Stage 1 – Initialization
As I previously said, I find it best to create all the elements in their own file. This file will then be placed into two events: Create and Key Press for the space bar. We need it in the Create event, as I have found that the Key Press event happens after the Keyboard event happens. Here is the code you need in scr_Particle_Init:
//create the system sys = part_system_create(); prt = part_type_create(); prt2 = part_type_create(); emt = part_emitter_create(sys); att = part_attractor_create(sys); def = part_deflector_create(sys); cha = part_changer_create(sys); des = part_destroyer_create(sys);
As you can see, we are creating variables for each of the elements we will be using, including two Particle Types. Emitters, Attractors, Deflectors, Changers and Destroyers all need to know what System they are apart of, so make sure you create the System first. It is important to name these variables simply as they are used in all the associated functions.
Stage 2 – Activate
We will only want the effect occurring while we have the space bar pressed, so this following script needs to go into a Keyboard event. All of the following code is going into scr_Particle_Active, but I will be adding in each element separately so that I can explain what it is going to do.
//System part_system_position(sys, x, y);
This code will simply ensure that the system is located at the origin of the spout object. All the parameters related to location in all the other functions will be based off of the system’s placement. This is important to remember, but I will point out why later.
//create particle type 1 part_type_shape(prt, pt_shape_disk); part_type_color1(prt, c_blue); part_type_speed(prt, 20, 24, 0, 0); part_type_direction(prt, 85, 95, 0, 0); part_type_gravity(prt, 0.8, 270); part_type_size(prt, 0.1, 0.2, 0, 0);
This is the code for the first particle and how it should act. Notice that each function here is asking for the variable name of the Particle Type we want. To start, I am using part_type_shape, which allows us to use one of Game Makers pre-built particle types. There are 14 types in all including ones for smoke, stars, rings, etc. In this case I am just using a small circle (disk). Next, we set the color, which I am using a single color only: blue. The Speed is set with a Minimum and Maximum velocity and the two options set to zero are for increasing of the speed and the wiggle (or variance) of the speed. The Direction is set with a Minimum and Maximum angle, and have similar options as speed for increase in angle over time and wiggle. Gravity is applied with a simple force and direction. Finally, the Size is set, which again, has Minimum and Maximum values with options for increasing the size over time and wiggle.
//create particle type 2 part_type_sprite(prt2, spr_myParticle, false, false, true); part_type_gravity(prt2, 0.8, 270); part_type_size(prt2, 1, 1.4, 0, 0); part_type_orientation(prt2,0,360,10,0,true);
There are two difference with the second particle. First, here we are using part_type_sprite, which is going to use the sprite we created. The three option after it are: Animation, whether you want it to play any animation you may have, Stretch, which will set the animation speed to the duration of the particle life, and Random, which will set it to a random frame within the animated sprite. We are using Orientation, which will rotate the sprite between the Minimum and Maximum values, with options for increasing rotation over time, wiggle and the final boolean value is whether it should follow the particles path precisely or not.
//create emitter part_emitter_region(sys, emt, -10, 10, -5, 5, ps_shape_line, ps_distr_linear); part_emitter_burst(sys, emt, prt, 2);
The Emitter is where things start to be come a bit more complicated. We need to declare the Region, which needs to know what system and emitter it is attached to. The four options with numbers is the X min / max and the Y min / max. This will create an area from where the particles can be created. The Shape of the dispersion is next, in which I am using ps_shape_line. There are four shapes in total: linear, rectangular, ellipse, and diamond. In this example, it doesn’t really matter which one you choose as they will all appear to be the same. The last option there is for how they are Distributed, and there are three options: linear (average), gaussian (more towards the center), and invgaussian (more towards the edges).
Finally, we have the function for the type of Emitter, in this case a burst, which will shoot out particles only once per call. The other function choice you have is a stream, which is good if you want something that doesn’t stop , but we don’t want that here. As you can see, these functions require the System, the Emitter and the Particle Type attached to it. The number at the end is the option for how many particle you want created each time it is called.
//create attractor part_attractor_position(sys, att, mouse_x-x, mouse_y-y); part_attractor_force(sys, att, 0.5, 120, ps_force_constant,true);
Here we are going to have an Attractor attached to the mouse location, which will pull the particle stream towards it. When positioning it, it is important to subtract the X and Y from the Mouse’s X and Y. I pointed out earlier when creating the system, all other parameters are relative to its location. If we didn’t subtract the values, then the mouse location would by default, be added to the system location. Therefore it would think the mouse was somewhere else completely, which wouldn’t be good. The final function here is the Force of the attraction. The first number is the force itself, followed by the distance away that particles can be affected. The next option is the Kind of force, here we are using a constant value, but we could have one that was linear (increases steadily) or quadratic (increases exponentially). The last option is for whether it is Additive on every step or not, which will increase it speed and direction in a relative manner.
//create deflector part_deflector_region(sys, def, -320, 320, 10, 120); part_deflector_kind(sys, def, ps_deflect_vertical); part_deflector_friction(sys, def, 16);
The Deflector is how we are going to make an imaginary floor from which the particles will bounce. As with other elements, we start out with a region of influence. I used -320 , 320 as that will cover a large distance and it too, is based from the system center point. The Kind of deflector you can have is either Vertical or Horizontal. Since we are faking a floor, we have chosen vertical. The last function is to add friction, and it will help cause the particles to come to rest.
//create changer part_changer_region(sys, cha, -320, 640, 5, 15, ps_shape_rectangle); part_changer_types(sys, cha, prt, prt2); part_changer_kind(sys, cha, ps_change_shape);
The Changer is going to change any of the circle particles that it collides with to become our sprite based particle. Again, we have a Region with a shape type option. The Types function just asks what the two particles are. Finally, the Kind has three options: Shape (which affects color, size, shape), Motion (speed, direction, rotation) or All (which essentially removes the particle and create a new one). Here we are only changing the look of it as we want it to react no differently.
//create Destroyer part_destroyer_region(sys, des, -320, -120, -480, 480, ps_shape_rectangle);
Our remaining element is the Destroyer. In this case, all we are doing is setting a region for which the particles will die if they come into contact with it.
Step 3 – Cleaning Up
Hopefully you are still with me here. There was a lot of code in that last file, but this final one is fairly simple. All we need to do is remove the system and all of its elements. This is highly important as these systems will live for ever, as in you can restart the game or change a room and they will still be there. This example is going to be a bit ugly as it will remove everything immediately upon release of the space bar. The following code should be in scr_Particle_Clean and be placed in the Key Release event for the space bar.
//Clean Up part_emitter_destroy_all(sys); part_attractor_destroy_all(sys); part_deflector_destroy_all(sys); part_changer_destroy_all(sys); part_destroyer_destroy_all(sys); part_system_clear(sys); part_system_destroy(sys);
Here we are removing the Emitter, Attractor, Deflector, and Destroyer from the system to ensure that they are gone. We then Clear the system, which will remove all the particles, and finally remove the system itself.
There you have it, a fully functioning water fountain that demonstrates the principles of each element of a particle system. This example just touched the surface of what you can do. Some of the other cool things we didn’t look at were the life of a particle, death, colors and color blending. If you want some ideas of what you can do, I recommend going to gmparticles.com as they have over 500 different examples with code!