Howdy folks! Welcome to yet another GameMaker Basics tutorial. Today, I would like to go over how to create effects in your games. If you have been following along with my previous GameMaker Basics blogs, then a lot of this may seem familiar to you. We will be creating an effect object, controlling its behavior with a state machine, and using scripts to streamline the creation of these objects in game. I would also like to point out that this is not a tutorial on how to draw, or design, effects. I’m no artist! However, you can click here to get the set of effects that I am using in this post.
If you are following along with the sprites I have provided, go ahead and get those set up in GameMaker. I went ahead and named them after the sprite files.
After you have all of the sprites added to your project, go ahead and create an object called oEffect. Do not assign a sprite to this object! We will be changing the sprite based on the type of effect we are creating.
Open up the oEffect object and add the following code to the create event.
oEffect Create Event
effectType = -1;
animationSpeed = 0.25;
xSpeed = 0;
ySpeed = 0;
Using the effectType variable, we will be able to change the behavior and sprite of our effects very easily using a switch statement. animationSpeed is pretty much what it sounds like. This will let us control how quickly the animation plays for our effects. xSpeed and ySpeed will control the horizontal and vertical movement of the effects.
While we are working on the oEffect object, let's go ahead and set up the switch statement. For this, we want to use the end step event.
oEffect End Step Event
switch ( effectType ) {
case 0:
//smoke
break;
case 1:
//spark 1
break;
case 2:
//spark 2
break;
case 3:
//spark 3
break;
}
This is just a general outline for our effect controls. We will come back to this later. Now, create one more object and name it oControl. This is what we will use to read our button presses, and spawn in our effects. Add the following code.
oControl Create Event
effectToCreate = 0;
This variable will allow us to easily change the effect we are spawning in game with a mouse click. The last thing we need to do before setup is complete is initialize our enums (for more information on enums, check on this blog post I wrote on state machines).
Create a new script and name it enum_init. Add the following code.
enum_init script
enum effects {
smoke,
spark1,
spark2,
spark3
}
This is basically just a list of variables that equal zero to three. This is what we set up our switch statement to use in the previous step. Finish up by creating a new room, whatever size you want, and drop your oControl object in the room.
Now that we have the basic setup out of the way, we can start making our effects appear on screen. We will do this by making the oEffect objects get created when we click the left mouse button. This is, of course, just an example of how to create these effects. In your game, you may want to create effects when a character is hurt, or when a coin is picked up. The same methods apply.
Let’s go back to the oControl object and set up some mouse clicks.
oControl Step Event
//change effect
if ( keyboard_check_pressed( vk_space ) ) {
effectToCreate ++;
if ( effectToCreate > effects.spark3 ) {
effectToCreate = 0;
}
}
//create the effect
if ( mouse_check_button_pressed ( mb_left ) ) {
//create effect
}
The first bit of code will allow us to change the effect we are trying to create by clicking the mouse button. It cycles from zero to three,and then back to zero, when the spacebar is pressed. You’ll notice that we don’t actually have any code to create an effect on mouse click. That is because we are going to create a script that will make creating effects much easier. Go ahead and create a new script and name it effect_create.
effect_create script
///effect_create( effectType, xPosition, yPosition, image_angle );
_e = instance_create(argument1,argument2,oEffect);
_e.effectType = argument0;
_e.image_angle = argument3;
return _e;
This script will make it very easy for us to create an effect whenever we want, wherever we want on the screen. When calling this script, four arguments are required. The first is the type of effect we want to create. The second and third arguments are the x and y position of where the effect will be created on screen. The final argument is the angle of the effect.
Now that we have the script, we can put it use. Head back to the oControl step event and update the //create the effect portion of the code.
oControl Step Event
//create the effect
if ( mouse_check_button_pressed ( mb_left ) ) {
e = effect_create ( effectToCreate, mouse_x, mouse_y, choose(0,90,180,270));
}
This will create an effect at the mouse position, at a random 90 degree angle. However, we have yet to define what these effects actually are. If you were to run the game and start clicking, nothing would happen. Which brings us to the next section…
After setting up the guts, creating new scripts, adding in the sprites, and making our clicker work, we are finally ready to draw some effects to the screen! Open the oEffect object and let's look at the end step event. We need to add some new code that will be universal to all effects, and some code to assign sprites to each case in the switch statement.
oEffect End Step Event
x += xSpeed;
y += ySpeed;
image_speed = animationSpeed;
switch ( effectType ) {
case 0:
//smoke
sprite_index = sprSmoke;
break;
case 1:
//spark 1
sprite_index = sprSpark_1;
break;
case 2:
//spark 2
sprite_index = sprSpark_2;
break;
case 3:
//spark 3
sprite_index = sprSpark_3;
break;
}
First, we want to change the x and y position of the effect based on the current xSpeed and ySpeed. This is universal for all of our effects. Since both of these variables are initialized as zero, the effect will NOT move unless you adjust either of those variables for the effect in question. I’ve also set the image_speed to equal our variable animationSpeed. This way we can change animationSpeed to whatever we want, whenever we want, and the sprite will be animated at that speed.
You’ll also see that I have added a sprite_index line to each switch case. By changing the sprite_index, we are changing the actual sprite which is drawn on screen.
Now, if you run the game, you should be able to click and an effect will be created. If you press the spacebar, the next time you click the effect should be different. However there is a problem… the effects are staying on screen. We need to delete the effect object once the animation has finished playing. For that, we need a script.
Create a new script and name it effect_destroy.
effect_destroy script
if ( floor ( image_index ) >= sprite_get_number ( sprite_index ) - 1 ) {
instance_destroy();
}
This is a very simple script that checks the current frame of animation the effect object is showing, and destroys the object if the current frame is higher than the maximum number of animation frames in the sprite. The sprite_get_number(); function will return the total number of frames in whatever sprite it is checking. In this case, our oEffect object is a different sprite_index based on the kind of effect that is playing. Open your oEffect end step event and add effect_destroy(); to the very last line. Run the game again and your effects should now delete after the animation has played.
At this point we are technically done, but we have a setup that allows us to make a lot of changes to how effects behave on screen. For example, if I add ySpeed = -1; to the first case, the smoke effect will rise. If you were to add ySpeed = 1; the smoke would fall.
Here are a few more examples using rotation, scale, and a much lower animationSpeed.
So, there you have it. By setting up effects using a single object, and a switch statement, it becomes very easy to manage a large number of different effects from a single location in your GameMaker project. You can add as many cases as you have effects in your game, and make adjustments to each one without having to create new objects or scripts. Thank you for taking the time to read over this, and I’ll catch you next time. As always, you can reach me on Twitter or visit my website for more gamedev stuff.
Nathan Ranney is the founder of game development studio Gutter Arcade. He's best known for the creation and development of Knight Club, an online indie fighting game.