GameMaker: Studio uses the well known Box2D physics library to give you the ability to create fast and efficient physics simulations in your game, and it works very well indeed! However, one of the limitations of Box2D is that it only simulates "rigid" bodies... However those clever chaps at Google have expanded the Box2D library to include their "Liquid Fun" module, which adds physics particles, giving you the ability to create fluid-like particle simulations as well as particle based soft-bodies. This module (v0.9.0) has now been integrated into GameMaker: Studio, and in this article we'll give you a brief overview of how it works...
NOTE: This article assumes you already have a good working knowledge of the physics functions and of GML in general.
As with the normal particle system (for creating graphics effects) the physics particles are designed to be a "fire and forget" system, in which you set up a series of properties and behaviours then create your particles and leave them to do their thing. The particles themselves can be created on an individual level, or as a group, and you can set different properties for each particle or group, as well as set some global properties which will affect all particles.
Now, in your physics games you should know that you can only have a single particle system (future updates may change this), and that setting the global properties for that system will not only change all subsequent particles created, but those already in the game room. So, if you use the new function
for example, to change the radius of the particle, you will change the radius of all the particles already in the room too (note that the particles that you create are really just single, circular fixtures and their global properties are pretty much the same as those that you would set for a regular fixture, like density, linear damping radius, etc... ).
That's not to say that you can't have different properties for each particle or each particle group, because you can! You can set a series of "flags" for each group or particle which changes their physical properties in some way, and you can also assign each particle or group to a specific user category so that you can change their flags using the appropriate functions at any time without affecting other particles in the physics simulation.
Since most of the particle functions are pretty much self-explanatory (and the manual has most of the information that you require to use them), we are going to concentrate our attention on only a few details, the first of which is the setting of particle "flags". The method used for setting flags on your particles is called "bit masking" and it can be quite confusing to people, especially if you've never used any type of binary maths! So let's have a look at what flags are available for our particles and how to use "bit masking" to set them...
To start with, let's look at the available particle types:
NOTE: 1 << 0 is not used for anything.
As you can see, each of these constants has a binary representation, like 1 << 4 for
What this means is that the constant represents 1 bit-shifted left 4 places. The image below should help you visualise this:
When you use binary numbers, you are limited to setting a "bit" to either 1 or 0, like switch that can either be on or off. This means that we can create a "bit-mask" of data, which is basically a row of zeros and ones, where each position represents a "switch" which will mark a certain property of our physics particle as being active or not. In the above image we have now flagged the particle as being elastic, but using this system you are not limited to setting particles to be of one specific type, since you can mask off as many bits as you need by using the bitwise or function (which is "|" in GML).
In the above image you can see that we now have a variable "flags" which holds a single value representing each of the bits set to change the particle properties. So, in the particle functions, when you see the "flags" argument, you simply have to select the constants required for the particle type you wish to create and bitwise or them together to get a single value, which is what you would use.
Note that not all particle types are compatible with each other and you may get some strange behaviours when setting, for example, a dust particle to have surface tension, so take some time to experiment with setting different flags and seeing what effect each one has on the particle system as a whole.
This type of bit-masking mechanism is used extensively with particles when setting individual properties, group properties, and also when getting data, so it is important that you understand how it works, and hopefully this short explanation has made it easier for you!
As mentioned previously, you can create individual particles, or particle groups. For individual particles, you set some flags and give a position and a velocity vector and a particle is created to go about it's business, but with groups you create a number of particles all at once within a defined shape. These particles will all have the same properties and will behave as a whole until they collide with any fixture in your game, at which point their behaviour will change depending on the flags that you have set for them.
For example, a circular particle group that has the default flags (ie: water) will break apart on collision with a fixture, but if you have set the "elastic" flag then it will not break apart, but rather bounce and behave as if the whole group was a single entity. This behaviour is what gives the impression of soft-body physics, even though we are still using a rigid-body physics library.
As a final note for using physics particles we are going to look at how they are drawn. There are two new functions for this:
physicsparticledraw(typemask, category, sprite, subimg)
physicsparticledrawext(typemask, category, sprite, subimg, xscale, yscale, ang, col, alpha)
When you create a particle you also supply a colour and alpha value for it, and these values will be used for the basic drawing, while the "typemask" is a mask of the properties to draw and the "category" is the user category that you assigned the particle. The "category" is an arbitrary integer value that is assigned when you create the particle and then used to identify them in this (and other) functions, and when combined with the "typemask" it permits you to very accurately select and draw only those particles that you wish.
For example, imagine that we have created a number of particles all with different flags and different categories. We only want to draw those particles that are flagged as viscous and have surface tension across all user categories. For that we would have this:
var mask = phyparticleflagviscous | phyparticleflag_tensile;
physicsparticledraw(mask, 0, sprBlob, 0);
This would draw all the particles that have flags matching the given mask in all user categories (setting the categories value to 0 tells GameMaker: Studio to include all categories in the function, so you cannot use 0 yourself to define a category), and they would be drawn using the given sprite, blended with the colour and alpha values that were specified when the particle was created.
The extended version of this function works the same way, only it gives you more control over the sprite properties that are used to draw the particle in the room, and you can also use the
function to get the x/y coordinates of the particle and then draw it yourself using the standard draw commands.
Although this article hasn't gone into too much depth on the physics particle functions themselves (the manual covers that!), we hope that it has helped clear up the basics behind how particles are defined and the properties that they can have, as that is undoubtedly the most complicated part of setting them up.
The important part to take away with you from all this is that bit masking is a common technique in programming and is very useful since it is fast and (once you understand how binary data is stored) very easy to use. GameMaker: Studio has made it even easier for you when using physics particles by providing constants for everything, but you should take note of the method used as you can create your own binary flags and masks easily and use them for a multitude of other tasks when making your games.