Project 1 UFO Attack! - Ludo Lodge...In order to install the GameMaker Studio 2 software, you must...

45
Revision 1.00 Project 1 UFO Attack! Project Description A UFO flying overhead is firing a variety of attacks down at your spaceship! You must dodge the threats while also hitting the UFO as much as possible in order to try and achieve the highest score. This project is all about providing an introduction to GameMaker and the basics of programming your first computer game. You will quickly learn how to make a ship move around on the screen using the arrow keys, as well as have different game objects interact with each other. The project assumes you have no prior experience with programming or GameMaker, so let’s go ahead and get started from the very beginning! Featured Artist Mary Langewisch @MaryFGI https://fragilegloryimpressions.com/ Key Concepts Creating a GameMaker Project Navigating the Editor Creating Resources Events and Actions Running a Project Alarms Variables Randomness Conditionals Playing Sounds New Actions

Transcript of Project 1 UFO Attack! - Ludo Lodge...In order to install the GameMaker Studio 2 software, you must...

Revision 1.00

Project 1 

UFO Attack! 

Project Description A UFO flying overhead is firing a variety of attacks down at your spaceship! You must dodge the threats while also hitting the UFO as much as possible in order to try and achieve the highest score. This project is all about providing an introduction to GameMaker and the basics of programming your first computer game. You will quickly learn how to make a ship move around on the screen using the arrow keys, as well as have different game objects interact with each other. The project assumes you have no prior experience with programming or GameMaker, so let’s go ahead and get started from the very beginning!

Featured Artist

Mary Langewisch

@MaryFGI

https://fragilegloryimpressions.com/

Key Concepts

■ Creating a GameMaker Project

■ Navigating the Editor

■ Creating Resources

■ Events and Actions

■ Running a Project

■ Alarms

■ Variables

■ Randomness

■ Conditionals

■ Playing Sounds

New Actions

Project 1: UFO Attack! Revision 1.00

Installing GameMaker Studio 2 In order to install the GameMaker Studio 2 software, you must first create an account on the YoYo Games website. Once you have an account, you should be able to download the free trial, either for Windows or Mac OS. Note that the free trial does not expire, but rather has limitations on the resources that you can put in your game, as well as limited export options. Don’t worry about that for now; all of the projects in this curriculum are designed to work completely in the free version of the software. Rather than explaining the steps for installation here, a link to the YoYo Games website is provided which should provide up-to-date information. Just make sure you select the Trial version that is free.

■ GameMaker Studio 2 Download Page: https://www.yoyogames.com/get

If you run into any confusion with the process, the following article from the GameMaker Studio 2 wiki may provide some additional guidance: https://help.yoyogames.com/hc/en-us/articles/115005901728-Installing-GameMaker-Studio-2

This project will walk you through all of the steps necessary to create your first game in GameMaker from scratch. However, GameMaker includes its own documentation that can be helpful for learning about parts of the program, or to answer questions that you may have. To view the documentation, select Help->Open Manual from the top menu bar. Certain sections of this guide will show the name of a page in the Manual that has more information about the topic being discussed, using the following format:

Folder ► Page If you are finding something confusing, or just want to learn more, be sure to take advantage of the Manual; it is a valuable resource!

@rlangewi 2 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Creating a Project Quick Start ► Start

Go ahead and open up GameMaker Studio 2 (referred to onwards as simply, “GameMaker”), and you will likely be greeted with a window that asks you to log in with your Yoyo Games account:

Figure 1.0. The YoYo Account Login window. You will want to enter in the same account information you used to download GameMaker, and click Login. You will need to be connected to the Internet the first time you log in so that it can verify your account, but in the future, you should be able to connect in “offline mode.” You should then see the main landing page for GameMaker, which contains a few different sections (Figure 1.1).

Figure 1.1. The landing page for GameMaker Studio 2. From here you can create a new project, or load an existing project.

@rlangewi 3 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

The main sections that we care about for now are the large panels that are labeled New and Open. These are what you will be able to click when you want to create a new GameMaker project, or open an existing project to work on. Additionally, the list on the far left will show projects that you have worked on recently, which you can use as a shortcut for opening them. For now, we want to create our first project, so simply click the New panel. GameMaker provides two different options when creating new projects (Figure 1.2).

Figure 1.2. Two types of GameMaker projects, we will focus on Drag and Drop for now. Since we are just starting out, choose the Drag and Drop option. This will allow us to use GameMaker’s visual programming framework that makes it easier to learn for the first time. As you become more advanced with GameMaker, we will transition to projects that use the GameMaker Language, but no need to worry about that yet. Once you select Drag and Drop, you should be able to name your project and select where you want to save it. For this project, it is recommended you use the name “UFO Attack!”

Navigating the Editor Quick Start ► Workspaces/Resources/Workflow

Now that you have created a project, you are now free to explore the GameMaker editor. This is where you will work on all the different parts of your game. We will discuss various options in the editor as we go along in the projects, but here are few key things to point out (Figure 1.3):

@rlangewi 4 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Figure 1.3. The layout of a new project in the GameMaker editor.

■ The Resource Tree - The panel on the right side of the screen shows a list of sections: Sprites, Tile Sets, Sounds, Paths, etc. This is where you will find all of the different pieces that make up your game. For now, there are no items underneath any of these sections (except Rooms, which creates room0 by default). Whenever you want to change something, you should be able to find it by looking in the Resource Tree.

■ The Menu Bar - Across the top, there is a row of buttons. These will let you perform basic project-related tasks such as opening a different project, saving your progress, and running you game.

■ The Workspace - The large empty space that makes up the majority of the screen is called a workspace. This is where you will open various windows that let you modify the resources in your game. You can create multiple workspaces (see the tab labeled Workspace 1?) to help stay organized, but we don’t need to worry about that right now.

The best way to get more familiar with the layout of GameMaker is to actually start making something, so let’s dive in!

@rlangewi 5 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Sprites Editors ► Sprites

In GameMaker, any images that you see on the screen (such as characters, enemies, etc.) are called sprites. You can load any image from your computer into GameMaker as a sprite, or you can draw your own using the built-in Sprite Editor. For this project, all of the graphics have been provided so that we can focus on the other aspects of making a game. In the future, it may be fun to explore drawing your own graphics to use in your games! Let’s start by creating a sprite for the player’s spaceship. Loading the player sprite:

1. Right-click anywhere in the blank workspace to bring up the menu shown in Figure 1.4.

Click the Resources->Create Sprite option to create a new sprite.

Figure 1.4. Menu for creating resources when right-clicking anywhere in the workspace. Note that some of your shortcuts may look different if you are running Windows.

2. You should see a window appear for the new sprite, as shown in Figure 1.5. In the top left corner, there is a Name field that has a default of sprite0. This is where we provide a name for our image, so change it to spr_player.

@rlangewi 6 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Figure 1.5. The Sprite Editor window.

In GameMaker, it is important that no two resources have the same name. To make sure that we don’t accidentally use the same name among Sprites, Objects, Rooms, etc., it is recommended that you use a prefix for each different type of resource. For example, Sprite names will all start with spr_ and Object names will all start with obj_.

3. Now click the Import button in the section below the Name, and select the player.png file

from the resource folder that was provided with this project. The window with the imported Sprite should look look like Figure 1.6.

Figure 1.6. The player Sprite in the Sprite Editor.

@rlangewi 7 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

4. Click the “X” in the top-right corner to close the Sprite Editor. The image for the player is now ready to be used in the game.

If you ever need to edit a Sprite, you can double click it in the Resource Tree to reopen the Sprite Editor. At this point, we have the Sprite for the player’s ship, but it is just an image that doesn’t do anything. In order to make the image move around and interact with other elements of the game, we will need to create an Object.

Objects Editors ► Objects

In GameMaker, Objects are the elements that are programmed to move around the screen and interact with each other. An object can be assigned a sprite that determines what image will be shown on the screen, and then actions can be assigned to trigger whenever certain events take place. To show how this works, let’s make an object for our player’s spaceship. Creating the player object:

1. Right-click anywhere in the blank workspace, just like you did when creating a new sprite.

Click the Resources->Create Object option to create a new object.

2. You should see the Object Editor as shown in Figure 1.7. Go ahead and change the name of the object to obj_player.

Figure 1.7. The Object Editor window.

@rlangewi 8 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

3. Click on the button that currently says No Sprite and choose spr_player from the window that appears.

Events and Actions Editors ► Events

Events and Actions are the keys to programming in GameMaker. An Event is something that happens in the game, and Actions are the directions for what an object should do when a particular event takes place. For example, here are some events and actions that we might want in our game:

Event (when this happens…)

Action (do this.)

The right arrow is pressed on the keyboard. The player’s ship moves to the right.

The space key is pressed on the keyboard.

Create a bullet object at the player’s location, moving up.

The player ship is touching an enemy bullet.

Destroy the player ship and restart the game.

Everything in your game is going to be made from objects that perform actions on certain events; it is actually that simple! This also means that the objects won’t do anything unless you tell them to do it. For example, if you don’t add an action that says that bullets should hurt the player’s ship, the bullets will just pass through without anything happening! Any time you want something to happen, you will need to think of what events and actions need to be added.

The first thing that we want to do is make it so that obj_player can be moved back and forth using the left and right arrow keys. Let’s start with the left direction, and add an event and action that will tell obj_player to move. Adding the keyboard left event:

1. From the Events window to the right of the Object Editor, click the Add Event Button. A

@rlangewi 9 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

menu will appear that shows a bunch of different types of events. Select the Key Down->Left event, as shown in Figure 1.8.

Figure 1.8. Adding the Key Down->Left event.

2. The previous step added the Key Down->Left event to the list of events that are active for obj_player. You will see another window open to the right of the Events window, as shown in Figure 1.9. This window shows the actions that are assigned to the Key Down->Left event, and right now, there aren’t any!

Figure 1.9. The list of actions for Key Down->Left, which is currently empty.

@rlangewi 10 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

3. From the sections of actions shown on the right, find the Set Direction Fixed action

(shown in the left margin) and add it to the actions list by either double-clicking it, or clicking and dragging it into empty actions area. You should see a block appear as shown in Figure 1.10. This action lets you set the direction of an object. In this case, since we are in the event for Key Down->Left, click the arrow that is pointing to the left.

Figure 1.10. The Set Direction Fixed action block.

4. The previous action set our object’s direction to the left, but for it to actually move, we need

to give it a speed. Find the Set Speed action and add it to the action list below the Set Direction Fixed action. The Set Speed action shows a few options: a Type choice box, a Speed field, and a Relative checkbox. You can leave the Type as Direction, which will use the direction that we already set to the left. The Speed value will determine how quickly our object moves. For now, use a value of 16. Leave the Relative checkbox unchecked for now, we will talk more about that option later on. Once you are finished, your action list should look like Figure 1.11.

Figure 1.11. Actions to make the object move to the left.

Whenever the instructions for this project involve adding an action to an event, the icons for the actions will be shown in the margin to the left.

You just did your first programming! Let’s walk through what we added, and how it will work. In our obj_player object, we added a Key Down->Left event, which will trigger whenever the player presses

@rlangewi 11 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

the Left key on the keyboard. In that event, we added two actions: one to set the direction to the left, and one to set the speed to 16. This means that whenever the Left key is pressed, GameMaker will execute your actions for that event in order (from top to bottom), setting the direction and speed, and the object will start moving! Enough with the explanation though, we want to see if it actually works! In order to do that, we first need to add a Room to our project.

Rooms Editors ► Rooms

In GameMaker, Rooms are the levels of your game where you can insert any objects that you have created. In order to test our obj_player object, we will need to create a room and place obj_player inside of it. Placing the obj_player object in a room:

1. Every GameMaker Project comes with a default room named room0. Locate this room in

the Resource Tree on the right. By either slowly double-clicking it, or right-clicking it and selecting Rename, set the name to be rm_level.

2. Double-clicking the room in the Resource Tree will open a separate tab that shows the empty contents of the room as a grid. To place obj_player in the room, simply drag it from the Resource Tree and drop it towards the bottom of the grid, roughly in the middle horizontally. You should see the player’s ship in the room as shown in Figure 1.11.

Figure 1.11. Room Editor with obj_player placed in the room.

@rlangewi 12 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

You will notice that the Room Editor is displayed on a separate tab from the workspace that you were using while creating Sprites and Objects (see Figure 1.12). In order to leave the Room Editor, you can simply click the tab for the workspace you want to access, or you can double click any other type of resource in the Resource Tree.

Figure 1.12. Tabs for switching workspaces. There are options for changing the size of the room, but the default size will work for this project. Now that we have our player object in the room, we should be able to test if it works! Before running the game, we should make sure that we save our project. To save, click the Save icon on the top toolbar (Figure 1.13) or select it from the menu: File->Save Project. Saving can also be done quickly with a keyboard shortcut: ⌘S on Mac, and CTRL+S on Windows.

Figure 1.13. Save button on the toolbar.

Make sure you save often! You never know when your computer might have a problem that causes GameMaker to close or need to be restarted before you have a chance to save. It is never fun to lose your work, so try to make a habit of saving after making any changes!

Running Your Game To run your game, simply click the Run icon from the top toolbar (Figure 1.14). You can also run the game by selecting Build->Run from the menu, or by pressing F5.

@rlangewi 13 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Figure 1.14. Run button on the toolbar. It will take a few seconds for GameMaker to build your project, but then a game window should appear that looks something like Figure 1.15.

Figure 1.15. Window with the game running. Now you can finally test to see if your actions for the Key Down->Left event are working properly! Press the Left arrow key, and you should see the spaceship move off of the left side of the screen. If the spaceship does not move left, first make sure the window is selected by clicking on it. If that still does not solve the problem, go back and make sure that your events and actions in obj_player match what was written in the previous sections.

@rlangewi 14 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

But wait… why did the spaceship not stop at the edge of the screen? And why can’t you move it back to the right? Remember, in GameMaker (and when doing any computer programming), the computer will only do what you tell it to do. At this point, the only directions that we have given GameMaker is for obj_player to move left when the Left arrow key is pressed. We did not add any instructions for when it should stop, nor did we add any actions for when the Right arrow key is pressed. Now that we see that the very basics are working, we can go back and finish adding our events and actions for obj_player.

Finishing the Player Movement Double-click obj_player in the Resource Tree to reopen the Object Editor. First, we want to add an event with actions to allow the player to move to the right. Adding the “move right” actions to obj_player:

1. Click the Add Event button, and select the Key Down->Right event.

2. Add the Set Direction Fixed and Set Speed actions to the actions list. Set the direction to be right, and set the speed to 16.

Now the player will be able to move in both directions, but they still won’t be able to ever stop! In order to stop the player, we will add events that trigger when the left or right arrow keys are released. Adding the “stop” actions to obj_player:

1. Click the Add Event button, and select the Key Up->Left event. A Key Up event is

triggered whenever the specified key is released.

2. Add the Set Speed action to the actions list with a Speed of 0. Now whenever the Left

arrow key is released, the speed of obj_player will be set to zero, which will stop it from moving.

3. Repeat the previous two steps for the Key Up->Right event. Your events and actions for obj_player should now look something like Figure 1.16.

@rlangewi 15 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Figure 1.16. The Events and Actions windows after finishing the movement for obj_player. Go ahead and save and run your game. You should be able to move the spaceship left and right now, and it should stop when you release either of the keys.

If you are adding an event that is very similar to an event you already have, you can save time by duplicating it. Simply right-click the event in the Events list, and select “Duplicate Event.” This will let you pick a new event, and will then create it and copy over all of the actions.

Giving the Spaceship a Weapon It is nice that we have a spaceship moving back and forth on the screen, but that really isn’t much of a game. As a next step, let’s add the ability for the spaceship to shoot a bullet when the Space key is pressed. First, we will want to add a sprite for the bullet. Creating the bullet sprite:

1. Right-click the Sprites section in the Resource Tree, and select Create Sprite, or

right-click anywhere in the workspace and select Resources->Create Sprite.

@rlangewi 16 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

2. Set the Name of the sprite to spr_player_bullet.

3. Click the Import button and select the file player_bullet.png.

4. Click the “X” in the top-right corner to close the Sprite Editor.

Now that we have a sprite for the bullet, we will want to add an object. Creating the bullet object:

1. Create a new object, and set its Name to obj_player_bullet.

2. Click the Button that says No Sprite and select spr_player_bullet.

Time to think about how we want our bullet to behave. When a bullet is first created, we want to set it to a fast speed, moving upwards. When the bullet goes off the top of the screen, we can go ahead and destroy it (otherwise it will just keep going up forever). GameMaker provides events that will make this easy. The Create event triggers once, right when the object is first created. This will be a great place to set the bullet’s direction and speed. Additionally, there is an Outside Room event which triggers if the object is ever outside the boundaries of our room. We can use this to know when the bullet should be destroyed. Let’s add those events and actions now.

Besides scrolling to find the actions that you are looking for, GameMaker will show your most recently used actions at the top of the list, and there is also a search bar where you can type to filter which actions are shown.

Adding the events and actions for obj_player_bullet:

1. Click the Add Event button and select Create.

2. In the Create event, add the Set Direction Fixed action and set the direction to up. Then add the Set Speed action, and set the Speed to a value of 32. These actions will only be triggered once, right when the bullet first appears in the room, and will fire the bullet upwards.

@rlangewi 17 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

3. Click the Add Event button again, and select Other->Outside Room.

4. Add the Destroy Instance action to the actions list for Other->Outside Room. This action

doesn’t have any additional values; it simply destroys the instance of the object from the room.

The windows for obj_player_bullet should now look something like Figure 1.17.

Figure 1.17. The windows after adding events and actions for obj_player_bullet. Unlike obj_player, our bullet objects don’t actually start in the room. Instead, we want them to be created on the fly whenever the player presses the Space key. Let’s look at how we can use the Create Instance action in obj_player to make this happen. Making bullets fire from obj_player when pressing the Space key:

1. Open the Object Editor for obj_player by double-clicking it in the Resource Tree.

2. Click the Add Event button and select Key Pressed->Space.

3. Add the Create Instance action to the actions list. Click the button to the right of the Object

field and select obj_player_bullet. This is the object that we want to create. The X and Y values define where on the screen the object should be created. Set X to 32 and Y to 0, and make sure to check the Relative checkbox for both X and Y. There are a couple of new concepts here, so read on as we walk through what these values mean.

@rlangewi 18 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

First, let’s talk about what X and Y values mean in GameMaker. In a room, every position has a corresponding X and Y value. The X value defines where the position is horizontally (right and left), and the Y value defines where the position is vertically (up and down). The values start at zero in the top-left corner, with X getting bigger as you move to the right, and Y getting bigger as you move down. See Figure 1.18 for an example of the X and Y values for different positions in our room.

Figure 1.18. Examples of different X and Y positions in our room, which is 1024 x 768 pixels in size. When creating our bullets, we set the X and Y values to be be 32 and 0. But wait, won’t that just create the bullets up in the top-left corner of the screen? This is where the Relative checkbox becomes very important. When the Relative option is checked, it means that it should measure the value relative to the current value for that object, in this case, our ship’s position. Our Create Instance action is in obj_player, which is where we want the bullets to be created. By selecting Relative for both the X and Y values, we are telling GameMaker to create the

@rlangewi 19 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

bullet “32 pixels to the right of the player, and 0 pixels below the player.” The 32 for the X value is simply to center the bullet above our spaceship, a value of 0 would actually create it aligned with the left side of the spaceship. In future projects we will learn about how this is controlled by the origin of our sprites, but you don’t need to worry about it for now.

The Relative option will be very important as we continue working in GameMaker. Just remember that when Relative is unchecked, GameMaker will simply use the exact value. When Relative is checked, GameMaker will measure the value from the current value. In this case, the current value was the position of the spaceship, but in the future it may refer to other values such as speed, health, or score.

Now is a great time to save and test your game. In addition to moving the spaceship with the arrow keys, you should also be able to press Space to fire bullets upwards. Make sure everything is working before moving on, and double-check the previous steps if you notice that something is not quite right.

Instances and Objects You may have noticed when we were adding actions such as Create Instance or Destroy Instance, that the word instance is used instead of object. It is important to understand the difference between these two terms. In GameMaker, instances of an object are what are actually in our room when the game is running. We can have as many instances of an object as we want; for example, there are multiple instances of obj_player_bullet at one time when you hit the Space key quickly, but you could even have multiple instances of obj_player! Go ahead and try it for yourself: just add some more instances of obj_player into your room, and run the game. You will notice that all of the different spaceships move and shoot together (make sure to remove these extra instances afterwards). An object on the other hand, is like a recipe for creating a new instance. You define the events and actions for an object in the Object Editor, but then you can create as many instances of that object as you want. Each instance will behave according to the same directions that you put into the object. So just remember… if we are talking about objects, we are referring to the single version in the Editor that has events and actions to define the object’s behavior. If we are talking about an instance, we are referring to a specific copy of an object that is actually present in the game room.

@rlangewi 20 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Adding an Enemy to Fight Now we can start getting into the fun stuff: actually having something to attack! You are probably starting to see a pattern with each new piece we add to our game: we first create a sprite, then we create an object that uses that sprite, and then we place the object in the room. Let’s go ahead and walk through those steps quickly for our enemy. Creating the sprite and object for the UFO:

1. Create a new sprite and name it spr_ufo. Click the Import button and select the file

ufo.png.

2. Create a new object and name it obj_ufo. Change the object’s sprite to be spr_ufo.

The UFO will have a simple moving pattern where it just moves back and forth horizontally, reversing direction whenever it reaches the edge of the screen. GameMaker provides an event specifically for when an object intersects the boundary of the screen, as well as an action to reverse an object’s direction, so this will be easy to add in. Making the UFO move back and forth:

1. Add a new event to obj_ufo and pick Create.

2. Add the Set Speed action to this event. Set the Direction to be Horizontal and the Speed

to be 12.

Note that when we programmed the movement for obj_player, we first set the direction using the Set Direction Fixed action, and then used the Set Speed action to set the speed in that direction. What we just did for obj_ufo has the same effect, just with a slightly different approach. The Horizontal option tells us that the speed will be in the left and right direction, where a positive number like 12 is to the right, and a negative number like -12 is to the left. There are many times in programming where there are multiple ways to accomplish the

@rlangewi 21 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

same thing, without one way being “right” or “wrong.” It is often comes down to just picking the option that makes the most sense to you!

3. Add a new event to obj_ufo and pick Other->Intersect Boundary.

4. Add the Reverse action to this event, and select the Horizontal option for the Direction.

Every time the UFO hits the edge of the screen, its horizontal speed should be reversed, causing it to move back and forth indefinitely. Now we just need to add the UFO object into our room. Double-click rm_level from the Resource Tree to open the Room Editor. Drag obj_ufo from the Resource Tree into the room, placing it somewhere along the top of the screen. Your room should look something like Figure 1.19.

Figure 1.19. rm_level with obj_ufo added towards the top.

@rlangewi 22 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Go ahead and run the game, and make sure that obj_ufo moves back and forth properly. If everything looks good, let’s go ahead and give the UFO a basic attack!

Making the UFO Fire Bullets We are going to start by giving the UFO a simple attack, periodically firing bullets down at the player. Unlike with obj_player, there is no key press that will trigger the creation of the UFO’s bullets. Rather, we just want the bullets to be fired every couple of seconds. To accomplish this, we will use GameMaker’s alarm events and actions, which allow you to program timers that perform actions after waiting for a certain amount of time. But first, we need to add the sprite and object for the UFO bullet. Creating the sprite and object for the UFO bullet:

1. Create a new sprite and name it spr_ufo_bullet. Click the Import button and select the

file ufo_bullet.png.

2. Create a new object and name it obj_ufo_bullet. Change the object’s sprite to be spr_ufo_bullet.

Similar to obj_player_bullet, we want obj_ufo_bullet to start moving when it is created, and destroy itself when it goes off the screen. However, we will want to make sure that obj_ufo_bullet moves downwards towards the player. Adding events and actions to obj_ufo_bullet:

1. Add a new event to obj_ufo_bullet and pick Create.

2. In the Create event, add the Set Direction Fixed action and set the direction to down. Then add the Set Speed action, and set the Speed to a value of 8.

3. Click the Add Event button again and select Other->Outside Room and add the Destroy

Instance action to the actions list.

@rlangewi 23 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Now we just need to have the UFO create these bullet objects every few seconds. We will put an alarm in obj_ufo to handle this. Each alarm that you use will be numbered, anywhere from Alarm0 to Alarm11. Each alarm has its own event that will trigger whenever that alarm goes off. For example, if you use the Set Alarm Countdown action to set Alarm0 to 30, then the Alarm0 event will execute its actions one second later. But wait… why is 30 only one second? This is because the alarm countdown is measured in what GameMaker calls steps. By default, GameMaker uses a frame rate of 30 frames per second (frames per second, or FPS, is the number of times the screen is redrawn each second), which means that each second is made up of 30 steps. This means that if you wanted to wait for five seconds, you would need to multiply 30 by 5, which would be a value of 150 steps. Just remember, unless we change the FPS of our game (which we won’t in these projects), 30 steps will always equal 1 second. We are going to make our UFO fire a bullet every two seconds. In order to do this, we will need to set an alarm when the UFO is first created, and then have that alarm create a bullet when it triggers. Additionally, we will need the alarm event to set the alarm again, so that way it keeps triggering the event over and over. Adding the bullet alarm to obj_ufo:

1. Open the Create event in obj_ufo.

2. Add the Set Alarm Countdown action to the actions list for the Create event. Set the

Alarm to be 0 and the Countdown to be 60 (two seconds).

3. Click the Add Event button again and select Alarm->Alarm 0. First, we want an action to

create the bullet, so add the Create Instance action to the list. Select obj_ufo_bullet for the Object, and set the X and Y values to be 55 and 25, respectively. Finally, make sure to check the Relative checkbox for both X and Y. Do you remember why the Relative option is so important? Without it, we would be creating the bullets way up in the top-left corner of the screen (55 pixels to the right and 25 pixels below the top-left corner), regardless of where the UFO is on the screen! Relative makes sure that we measure from the UFO instead of the top-left corner, and we use the values of 55 and 25 to position the bullet to come out of the middle of the UFO.

4. In order for the UFO to fire a bullet every two seconds, instead of just once, we need to set

the alarm again at the end of the Alarm0 event. Add the Set Alarm Countdown action and set it to the same values, with the Alarm as 0 and the Countdown as 60.

@rlangewi 24 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Now you should be able to run your game and see the UFO fire a bullet every two seconds. Things are starting to look like more of a game! However, right now the player’s bullets don’t do anything to the UFO, and the UFO’s bullets don’t do anything to the player! Our next steps will be to increase the player’s score every time their bullets hit the UFO, and then make the player lose when they get hit by an enemy bullet. But first, let’s talk a little bit more about what a step means in GameMaker, and what is actually happening under the hood when your game is running.

The Gameplay Loop in GameMaker So far, you have seen how we can program events and actions for different objects, and then the actions will update what the player sees on the screen, such as the spaceship moving left, or a bullet appearing and moving upwards. Behind the scenes, GameMaker is repeatedly checking for these events, and redrawing what the player sees on the screen. Take a look at Figure 1.20 which shows a diagram of what happens during each step.

Figure 1.20. Cycle between executing actions and drawing the screen each step.

@rlangewi 25 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

The first thing that happens during each step is that GameMaker checks the events for every single instance that is currently in the room. For example, for every step that obj_player is in the room, GameMaker will check to see if either the Left or Right keys have been pressed or released, as well as if the Space key has been pressed. If any of these events trigger, then GameMaker will walk through the actions list for that event from top to bottom, and execute each action. While all of this is happening, no changes are being made to what is shown on the screen. Only once all the events for every instance have been checked, GameMaker then goes ahead and redraws the entire screen using the updated values of every object. This seems like a lot of work just to update tiny movements on the screen. Lucky for us though, computers are really really fast! In fact, the computer is able to check all the events and actions, and redraw the screen, 30 times per second! As a result, the player sees the objects moving around quickly and smoothly, completely oblivious to everything that is being checked and executed behind the scenes.

Scoring Points Scripting ► Drag_And_Drop_Reference ► Instance_Variable_Actions

The goal of our game is to score the most points by hitting the UFO with the spaceship’s bullets. In order to keep track of the player’s score, we will need to use what is called a variable. A variable is simply a container with a name that keeps track of a value. For example, values such as score, lives, health, etc. can all be tracked using variables. Variables can even hold more complex values such as a list of words or a specific instance of an object on the screen. All you need to remember for now, is that any time we want to keep track of a value, we can store it in a variable. There are a lot of variables that come built-in to GameMaker. For example, every object has x and y variables that track the position of an instance in the room, as well as variables such as speed, direction, and visible. Additionally, GameMaker provides variables and actions for each object to track its own score, lives, and health. In order to add scoring into our game, we are going to add an object named obj_controller that will be responsible for keeping track of the score, and also drawing the score on the screen. Unlike all of the objects we have created so far, obj_controller won’t actually have a sprite, and therefore won’t be visible on the screen! But even an object without a sprite still triggers its events and actions, and it is common to have these kinds of “controller” objects that take care of parts of the game in the background. We don’t need to import a sprite, so let’s jump straight into creating the obj_controller object.

@rlangewi 26 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Creating obj_controller and adding it to rm_level:

1. Create a new object and name it obj_controller. Leave the sprite set to No Sprite.

2. Click the Add Event button and select Draw->Draw and add the Draw Instance Score action to the actions list. You can leave the default values: this will draw the score with a caption that says “Score:”, and it will draw it in the top-left corner (X = 0, Y = 0).

3. Open up rm_level and add obj_controller into the room. You can place the object anywhere you want, though it is recommended that you place it in the top-left corner so it is easy to find later if we need to. You will notice that the object shows up as a gray circle with a question mark (Figure 1.21). This is just the placeholder image in the Room Editor for objects that do not have a sprite. When you actually run the game, you won’t be able to see the object at all.

Figure 1.21. obj_controller in the Room Editor; the gray circle won’t show up in the game. We introduced a new event here, the Draw event. You may remember from Figure 1.20 that redrawing the screen is something that happens during every step, which is normally 30 times per second. Therefore, when you add a Draw event, it is going to trigger every single step while the instance is active in the room! The only actions that you can add to a Draw event are actions that specifically draw elements to the screen (actions with yellow backgrounds), or ones that modify drawing settings like colors or fonts. In this case, we are using the action that draws the score. This just means that every step, obj_controller will redraw the score so that it is always up-to-date, even when the score changes.

Once you add a Draw event to an object, the sprite for that object is no longer drawn! This is because you are “overriding” the Draw event which disables its normal behavior of drawing the object’s sprite. If you want to use an object’s Draw event and still show its sprite, you will need to use the Draw Sprite action.

@rlangewi 27 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Now that you have obj_controller drawing the score, and it is placed in the room, you can try running the game. You should see a small caption in the top-left corner of the screen that shows that the current score is 0. But we still need to add a way for the score to actually go up! We specifically want the score to increase whenever the player’s bullets hit the UFO. Increasing the score when bullets hit the UFO:

1. Open the Object Editor for obj_ufo and add the Collision->obj_player_bullet event. A

Collision event will trigger during every step where the object is overlapping the specified collision object on the screen. So if ever an instance of obj_player_bullet is touching obj_ufo (which means the player hit the UFO), it will execute the actions in the event.

2. Whenever a bullet hits the UFO, we want the score to increase. Add the Set Score action

to the actions list for the Collision->obj_player_bullet event. There a few important details we will need to modify on this action. First, set the Score value to be 100. However, we want to add 100 to the score, not set the score to 100. Therefore, we need to make sure to check the Relative checkbox. If we don’t set the value to be Relative, then the action would always set the score to exactly 100, and it would never get any higher. Second, we need to make sure that we are setting the Score for the right instance. Every instance in the room can technically have its own Score value, but we want to update the Score for obj_controller, because that is the object that is actually going to draw the score to the screen. By default, every action will execute its effect for the object that is triggering the event. However, by changing the action scope, you can have the action be executed for a different object (or group of objects). In this case, our collision event is in obj_ufo, but we want to increase the Score value in obj_controller. To do this, click the small drop-down arrow to the right of the name of the action (Figure 1.22).

Figure 1.22. Changing the action scope so that the action is executed by a different object.

@rlangewi 28 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

This will open up a window that lets you select which object you want to execute the action. Click on obj_controller. You will notice that the action now shows a thin purple outline. This is a reminder that the action is currently set to execute for a different object. Additionally, the action summary to the left describes how the action is configured (Figure 1.23)

Figure 1.23. An action with its scope set to a different object. This action should now increase the Score for obj_controller by 100 whenever obj_player_bullet collides with obj_ufo. For more information on applying actions to other instances, see the following page in the GameMaker manual:

Scripting ► Drag_And_Drop_Overview ► Applying_Actions

3. In addition to increasing the score, we also want to destroy the bullet that hit the UFO. We

will use the Destroy Instance action that we used before, but putting that action here will actually destroy obj_ufo! This is another example of needing to change the action scope so that it is executed for a different object. We want the player’s bullet that hit the UFO to be destroyed, so you might think that we could set the scope to be obj_player_bullet. However, choosing obj_player_bullet will actually destroy every instance of the player’s bullets on the whole screen! That’s not what we want, we only want the bullet that hit the UFO to be destroyed. This is a perfect example of when to use the Other scope. In a collision event in GameMaker, the Other scope will always refer to the other instance that was involved in the collision. Since we are in the Collision->obj_player_bullet event for obj_ufo, the Other scope will refer to the specific instance of obj_player_bullet that caused the collision. This is exactly what we want. Add the Destroy Instance action to the actions list for the Collision->obj_player_bullet event. Click the small drop-down arrow to change the action’s scope, and select Other. Your actions for this event should now look something like Figure 1.24.

@rlangewi 29 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Figure 1.24. Actions for obj_player_bullet colliding with obj_ufo.

Go ahead and run the game now. If everything was set up correctly, you should see the player’s bullets hit the UFO, increase the score by 100, and then get destroyed. We are getting much closer to having a game now!

Losing the Game It is great that we can score points, but there is still no way for the player to lose because the enemy bullets just go straight through the spaceship. We need to add a collision event so that the player will lose if they get hit. Normally, a game might return you to a title screen after losing the game, but we are going to keep things really simple and just restart the game immediately. Restarting the game when the player is hit:

1. Open the Object Editor for obj_player and add the Collision->obj_ufo_bullet event.

2. Add the Restart Game action. No values to adjust here; this action simply restarts the

game!

That was easy, now the game should restart whenever the player is hit by one of the UFO’s bullets! As always, test and save before moving on.

Adding More Challenge We have all of the pieces for our game to be functional now, but you may notice that it is kind of boring. This is mainly because the UFO’s attacks are predictable and not very difficult to dodge. In this section, we will look into how we can use randomness to increase the challenge, as well as add some new attack types to provide more variety.

@rlangewi 30 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Firing Bullets in Random Intervals Scripting ► Drag_And_Drop_Reference ► Random_Actions

In obj_ufo, we set Alarm 0 in the Create event for 60 steps (2 seconds). Then in the Alarm 0 event, we had the UFO fire a bullet, and then set Alarm 0 again for 60 steps. We can leave the alarm in the Create event (it only happens once), but let’s look at how we can change the repeating alarm to pick a random value instead of always using 60. Using a random value for the UFO bullet alarm:

1. Open the Object Editor for obj_ufo and double-click the Alarm 0 event to view the current

action list.

2. GameMaker provides an action that can generate random values. We will use this action to

pick a random number within a range, and then use the result as the Countdown value for the Set Alarm Countdown action. Add the Get Random Number action and place it between the Create Instance and Set Alarm Countdown actions that are already in the list (simply drag the icon in between the other two). We are going to have the action pick a random number between 40 and 80. First set the Type to be Integer. If we wanted to allow values that are in between whole numbers such as 1.5 or 3.1415, we would use the Decimal type. Then set the Minimum to be 40 and the Maximum to be 80. The Get Random Number action also requires a name for the Target. The Target is just the name of the variable that will hold the random value so that we can use it later. You may remember how a variable is just a name that keeps track of a value, like score, for example. We will discuss the use of variables more later, but for now just set the Target to countdown and check the Temp checkbox. The Temp checkbox tells GameMaker that this variable is temporary, and we don’t need to keep track of its value past this step like we do with score.

3. Now that we have a random value from 40 to 80 stored in the countdown variable, we want

to use that value for the Set Alarm Countdown action instead of 60. Simply change the Countdown value to be countdown. When you put the name of a variable instead of a value, GameMaker will use the value that is currently stored inside of that variable whenever the action is run. Your actions for the obj_ufo Alarm 0 event should now look something like Figure 1.25.

@rlangewi 31 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Figure 1.25. Waiting anywhere from 40 to 80 steps between firing UFO bullets.

4. There is one more key piece that we need to add now that we are working with random

numbers. When your game starts, GameMaker uses what is called a random seed to determine the random numbers that are generated. This means that if the random seed is the same, GameMaker will always generate the same random numbers in the same order. For example, our Get Random Number action might pick the values 76, 61, 44, and 47 for the first four values. If you restarted the game with the same random seed, GameMaker will pick those same values in order: 76, 61, 44, and 47. That doesn’t seem very random, does it? However, this can sometimes be very useful for testing. If you are trying to figure out why something isn’t working properly, it is easier to test if the random results are the same each time you run the game. For our purposes though, we want the random results to always be different. Fortunately, GameMaker provides an action that lets us pick a different random seed, which will give us different results. We just need to call it once at the beginning of the game, and it will ensure that the random numbers we pick will be different each time. Since we just need to call the action once at the beginning of the game, we are going to put the action in our controller object. Open obj_controller and add an Other->Game Start event. Find the Randomize action and add it to the list. Now when the game starts, our controller object will make sure that we are really picking random numbers!

@rlangewi 32 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

If you run the game now, the bullets should sometimes fire sooner than 2 seconds, and sometimes after more than 2 seconds. It may be a little hard to tell, but the slight differences will help to keep the player on their toes. Things are still pretty easy though, so let’s spice things up by introducing a few different types of UFO attacks.

Making the UFO Fire Rockets Besides firing normal bullets, we are going to make the UFO occasionally fire rockets that move more quickly towards the player. The steps here are going to be almost the same as for obj_ufo_bullet, so they should start to feel familiar. Adding a rocket attack for the UFO:

1. We first need a sprite for the rocket. Create a new sprite and name it spr_ufo_rocket.

Import the ufo_rocket.png image for the sprite.

2. Our rocket object is going to behave almost exactly the same as obj_ufo_bullet, so we can save time by duplicating our existing bullet object. Find obj_ufo_bullet in the Resource Tree, right-click it, and select Duplicate. Rename the new object to be obj_ufo_rocket and change its sprite to be spr_ufo_rocket.

3. The only thing that will be different about spr_ufo_rocket compared to obj_ufo_bullet

is that the rocket will be faster. Open the Create event and change the Set Speed action to use a value of 32, instead of 8.

4. Now we just need to have obj_ufo fire the rocket objects on a timer. Open the Object

Editor for obj_ufo, and open the Create event. We want to add a new alarm for creating rockets, just like we did for the bullets. If you click the small plus sign (+) to the left of the Set Alarm Countdown action, it will allow you to add another alarm (Figure 1.26).

Figure 1.26. Expand an action to enter additional values.

@rlangewi 33 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

In the new section of Set Alarm Countdown, set the value of Alarm to 1, and Countdown to 90. The resulting action list should look something like Figure 1.27.

Figure 1.27. Setting the initial alarms for both bullets and rockets.

5. Now we need to add an event for Alarm 1, which is our alarm that is controlling the rockets. Since the actions we will be using are very similar to the ones in the alarm used for bullets, go ahead and right-click the Alarm 0 event in the Events list and select Duplicate->Alarm->Alarm 1. We will be using the same actions, but changing a few of the values. First in the Create Instance action, change the Object to be obj_ufo_rocket. Next, change the Minimum and Maximum values in the Get Random Number action to be 60 and 90 respectively. Finally, change the Alarm in the Set Alarm Countdown action to be 1 (if we left it at 0, it would just start calling Alarm 0 and we would just fire bullets instead of more rockets).

6. Lastly, we need rockets to actually hurt the player. This is easy to add because it is just the

same logic as what we added for obj_ufo_bullet. Open obj_player, right-click the Collision->obj_ufo_bullet event, and select Duplicate->Collision->obj_ufo_rocket. That’s it! Now the Restart Game action will be called when the player is hit by rockets.

If you play the game now, you should notice that the rockets make things a little more difficult, as well as more interesting. This is a step in the right direction, let’s continue by adding another attack that is even less predictable.

@rlangewi 34 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Making the UFO Fire Randomized Blades The two attacks that we have added to the UFO so far both shoot straight down, and are always the same speed. We are going to mix things up by adding an attack that shoots at both random angles and random speeds. Once again, this will be similar to what we have added for the other attacks, changed slightly to add the random elements. Adding the blade attack:

1. Create a new sprite and name it spr_ufo_blade. Import the ufo_blade.png image for the

sprite. Then duplicate obj_ufo_bullet (right-click it in the Resource Tree and select Duplicate), change the name to obj_ufo_blade, and change the sprite to spr_ufo_blade.

2. Open the Create event of obj_ufo_blade. Go ahead and delete both of the actions that

are currently in the list (Set Direction Fixed and Set Speed) by clicking the small x’s in the top-right corner of the actions. The actions we will use to make the direction and speed randomized will be similar, but it will be easier to understand if we start from scratch. First, as we did before, we need to generate a random number. This time, the number will be for the direction of the blade. How do we set direction as a number? In GameMaker, every object has a direction variable that is represented by a number from 0 to 360, which matches the degrees of a circle. See Figure 1.28 for a visualization of how the values correspond to the different directions.

Figure 1.28. The degrees of a circle, which are the values used by the direction variable.

@rlangewi 35 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

We want the blade to always shoot downward, but just at different angles. Let’s say that our minimum angle will be 225°, and our maximum angle will be 315°. Add the Get Random Number action and set the minimum and maximum to those values. We can leave the Type as Decimal, because we are okay having values that are in between the whole numbers. Set the Target to be direction, and this time leave the Temp box unchecked. You may notice that when you start typing in the word direction, a whole dropdown of name suggestions appeared below the text box, and direction was listed as a “Built-in Variable.” This is GameMaker telling you what options might exist for what you are trying to type, and it shows that direction is a variable that is built into every object. Previously, we stored our random number in a temporary variable, and then used that variable to set the value of an alarm. Here, we are actually putting the random value directly into the direction variable, and we don’t even need another action to set the direction! Just remember, the Target is where we want to put the random number, so we can set it directly into an existing variable if we know the variable name (and GameMaker’s drop-down suggestions can help you to remember).

3. Now that we set the direction of the blade to a random value, we also want to pick a

random value for the speed. Add another Get Random Number action, and set the Minimum and Maximum values to be 8 and 32. That way, our blades could go as slow as the UFO’s bullet, as fast as the rocket, or anywhere in between! Once again, we can set this random number directly into the speed variable that controls an object’s speed. Set Target to speed, and leave Temp unchecked. Just like with direction, we won’t need to use a Set Speed action, because we already put the random number into the speed variable directly! Your actions for the Create event of obj_ufo_blade should now look something like Figure 1.29.

Figure 1.29. Randomly set the direction and speed of obj_ufo_blade.

@rlangewi 36 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

4. Just like obj_ufo_bullet and obj_ufo_rocket, we need to add an alarm to obj_ufo that

periodically fires our blade objects. Open the Object Editor for obj_ufo and open the Create event. Add an additional alarm to the Set Alarm Countdown action (by pressing the “+” symbol) and set Alarm to 2 and Countdown to 120 (which is 4 seconds).

5. We want to shoot blades whenever the Alarm 2 event triggers, which is nearly identical to how we set up Alarm 0 and Alarm 1 for obj_ufo_bullet and obj_ufo_rocket. To save time, go ahead and duplicate Alarm 1 (right-click and select Duplicate Event), and select Alarm->Alarm 2 as the new event. Update the Create Instance action to reference obj_ufo_blade. You can leave the Minimum and Maximum values for the Get Random Number action as 60 and 90. Finally, make sure the Set Alarm Countdown action is setting the timer for Alarm 2.

6. Lastly, the blades need to hurt the player. Open obj_player, right-click the

Collision->obj_ufo_bullet or Collision->obj_ufo_rocket event, and select Duplicate->Collision->obj_ufo_blade.

Go ahead and try it out! If everything went well, the UFO should now occasionally shoot blades that have a random direction and speed. Make sure that the blades shoot differently each time, and that the game restarts when one hits the player. This is starting to make the game a lot more interesting! However, you may still find it too easy, and the difficulty doesn’t change at all while playing. This makes things kind of boring, especially if the player is good at the game (they might never lose!). Next, let’s make the game get gradually more difficult the longer the player stays alive.

Gradually Increasing the Difficulty Scripting ► Drag_And_Drop_Reference ► Common_Actions ► assign_var

Part of the reason why the game is not very difficult right now is because the UFO does not attack very rapidly. To make the game more difficult, we can set the alarms for each of the attacks to smaller values, making them fire more often. However, we don’t want the game to always be harder, but rather we want it to start out easy, and slowly get more difficult over time. To accomplish this, we are going to introduce our own variable called difficulty. Just like the score variable, difficulty is simply going to keep track of a number. At the beginning of the game, the difficulty will be 0, and every three seconds, we will add 1 to the difficulty. The way that the difficulty variable will actually affect the game, is by shortening the Countdown value of the UFO’s attack alarms by the current difficulty.

@rlangewi 37 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

For example, at the beginning of the game, difficulty is equal to 0. Therefore, if we set an alarm to a value of 60 - difficulty, it will set the alarm for 60 steps. However, suppose difficulty increases to a value of 20. Now when the alarm is set to a value of 60 - difficulty, it will actually be set for 40 steps, which will make the bullets shoot more frequently. We will need to make sure the difficulty doesn’t get too high (for example, a difficulty of 70 would cause the alarm to have a negative value!), but that still leaves plenty of room for the game to get really challenging! Adding a difficulty variable:

1. Since obj_ufo is the only object that will use the difficulty value, that is where we will

put it. Open the Object Editor for obj_ufo and open the Create event. When we added the score variable, there was a built-in action called Set Score. Whenever we want to make our own variables, we will use the generic Assign Variable action. Add the Assign Variable action to the action list for the Create event (the position in the list doesn’t matter, but it is recommended to set your variables at the top). Set the Name of the variable to difficulty, and leave it at a value of 0.

Be careful and make sure that you spell your variable names correctly! If you ever make a typo when entering the name of a variable, GameMaker will assume that you are talking about a new variable, instead of the one you meant to reference. For example, “difficulty” and “difficutly” won’t point to the same value.

2. Now we need the difficulty variable to increase by one every three seconds. Just like

we use a repeating alarm for all of the UFO’s attacks, we will have an alarm that increases the difficulty every three seconds. First add another alarm to the Create event for obj_ufo. The three attacks are already using alarms 0, 1, and 2, so set this Alarm to 3. Every second is 30 steps, so for three seconds, we need to set the Countdown value to 90.

3. Add a new Alarm->Alarm 3 event to obj_ufo. To make sure that the difficulty doesn’t get too high (we don’t want our alarms to ever have a countdown of less than zero), we are only going to allow the difficulty to increase up to a maximum of 35. How can we tell GameMaker to only do an action if the difficulty is less than 35? In programming, this kind of logic is accomplished using what are called conditionals. This simply means that certain actions will only be executed if a specific condition is true. In our case, we have the condition, “Is difficulty less than 35?” If that is true, we want to add one to difficulty, and then set Alarm 3 for another three seconds. If that condition is

@rlangewi 38 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

false, we want to ignore those actions, as the difficulty is not allowed to exceed 35. The Drag & Drop system in GameMaker represents these conditional actions using a green background. If you ever see a green action, you know that it will be used to determine whether the actions after it should be executed or not. This can be a little confusing at first, so let’s look at how we will keep difficulty from going over 35. Add the If Variable action to the actions list for the Alarm 3 event. Change the Variable to be difficulty, select Less from the drop-down menu, and set Value to 35. This defines our condition that must be true in order for the following actions to execute. You’ll notice it says “Empty” in red letters next to the action. This is because, currently, there aren’t any actions assigned to this conditional.

4. If the difficulty is less than 35, the first thing we want to do is increase the difficulty

by one. Add the Assign Variable action, but instead of just adding it to the bottom of the actions list, make sure that you drag it to the right of the conditional action. This shows that it should only execute if the condition is true, and the action should be indented to the right as shown in Figure 1.30.

Figure 1.30. Actions assigned to a conditional are shown offset to the right. Go ahead and change the Name in the Assign Variable action to be difficulty, set the Value to 1, and check the Relative checkbox. Relative is important here, because we don’t want to set the difficulty to 1 every time, but instead we want it to add 1 to the current difficulty.

5. Finally, add the Set Alarm Countdown action, again making sure that it is indented

underneath the If Variable conditional. Set the Alarm to 3 and the Countdown to 90. Your

@rlangewi 39 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

final action list for the Alarm 3 event should look something like Figure 1.31.

Figure 1.31. If difficulty is less than 35, add 1 to difficulty and set Alarm 3 for three seconds.

We now have a difficulty variable that increases by 1 every three seconds, until it is equal to 35. But right now that variable doesn’t do anything else! We need to actually hook up difficulty so that the higher it gets, the shorter the alarms between the UFO’s attacks get. This is as simple as subtracting difficulty from the Countdown value whenever we set the alarms for each attack. Making the attack alarms shorter when difficulty increases:

1. Open the Object Editor for obj_ufo and open the Alarm 0 event (which controls firing

obj_ufo_bullet). In the Set Alarm Countdown action, change the value from countdown to countdown - difficulty. This equation will take whatever random value was placed in countdown by the Get Random Number action, and then subtract whatever difficulty happens to be at the time (it will be increasing by one every three seconds).

2. Repeat the above step for the Alarm 1 and Alarm 2 events, so that difficulty will apply to the obj_ufo_rocket and obj_ufo_blade attacks as well.

@rlangewi 40 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Now is the moment of truth! Go ahead and test your game and see if you notice that attacks getting faster the longer you play. If you want to see what the game is like to play at the maximum difficulty, simply go into the Create event for obj_ufo and make difficulty start at 35 instead of 0 (just make sure to change it back!).

Improving the Player Input Currently, if the player wants to shoot bullets rapidly, they must keep pressing the Space key over and over. Not only is this kind of a nuisance, but it also might not be good for the player’s keyboard! It would be much better if the player could simply hold the spacebar, and have the bullets fire at a constant rate. When we added bullets to obj_player, we used the Key Press->Space event. A Key Press event only triggers once when the key is first pressed, which is why the player must continually press the Space key over and over again to fire more bullets. A different option is the Key Down event, which will trigger every single step that the key is held down. This would allow the player to hold the Space key down to keep shooting, but it would cause a bullet to be fired every step; 30 times a second! That would be a little much, we would rather have it fire six times a second, or every five steps. We will accomplish this by having a variable that tells the Key Down event whether it should fire a bullet or not, and have that variable reset every five steps. Allow the player to hold the Space key to fire bullets:

1. Open the Object Editor for obj_player and add a Create event. Add an Assign Variable

action, with a Name of can_shoot and a value of true. Whereas our previous variables all contained numbers, we will treat can_shoot like a boolean variable, which is simply a variable that is either true or false. The plan is to set can_shoot to false after firing a bullet, and then have it set back to true after 5 steps. We will only allow bullets to be fired if can_shoot is true, so that way the player can hold down the Space key and have bullets fire every 5 steps.

2. Right-click the Key Press->Space event for obj_player. Choose Change Event and switch it to a Key Down->Space event. Now the event will trigger every step that the Space key is held down, instead of just once when it is first pressed.

3. Open what is now the Key Down->Space event. We no longer want to always fire a bullet

in this event, instead it should only fire if can_shoot is true. Any time we want an action to only execute if a certain condition is true, we can use a green conditional action. Add the If

@rlangewi 41 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Variable action above the existing Create Instance action, and make sure that you drag the Create Instance action to the right of the If Variable conditional, so that it is shown indented to the right. Set the Variable of the If Variable action to can_shoot, and set the other values to check if it is Equal to true.

4. Add an Assign Variable action under the Create Instance action, still indented under the

If Variable conditional that is making sure that can_shoot is true. Set the Name to can_shoot and the Value to false. This way, after firing a bullet, the If Variable conditional action will prevent it from firing any more.

5. However, we don’t want can_shoot to remain set to false; otherwise the player would

never be able to shoot ever again! Instead, we want to set a timer for 5 steps, which will then set can_shoot back to true. Add a Set Alarm Countdown action to the list of actions indented under the If Variable conditional action, and set Alarm to 0 and Countdown to 5. Your Key Down->Space event should now look something like Figure 1.32.

Figure 1.32. Make sure that the player can only fire a bullet every 5 steps.

@rlangewi 42 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

6. The last piece we need is to have the Alarm 0 event set can_shoot back to true. Add an

Alarm->Alarm 0 event, and add the Assign Variable action. Set the Name to can_shoot and the Value to true.

Time to test out the changes! Make sure everything is working as you would expect, and that holding down the Space key fires a constant stream of bullets. If you ever wanted to make the player fire bullets more quickly or slowly, you would simply need to go into the Set Alarm Countdown action in the Key Down->Space event for obj_player, and change Countdown from 5 to a different value.

Adding Sounds Editors ► Sounds

While the focus of this project is on the programming side of GameMaker, it is always fun to add sounds to our games! Let’s look at how you might add a sound for when the player’s bullets are fired. Adding a sound when the player’s bullets are fired:

1. First we need to add a sound resource. Just like a sprite, object, or room, you can add a

new sound by right-clicking anywhere in the workspace and selecting Resources->Create Sound or by right-clicking the Sounds directory in the Resource Tree and selecting Create Sound. Set the Name of your first sound to be snd_player_bullet and click the “…” button to the right of the Name field to select a sound file. Select the player_bullet.wav file that was provided with the project.

2. Now we simply need to play the sound whenever a bullet is fired by the player. Open the

Object Editor for obj_player_bullet and open the Create event. Add the Play Audio action to the actions list, and set the Sound to snd_player_bullet.

Try running the game and see if the sound is working! Adding sounds is pretty simple as long as you pick the right event for the Play Audio action. One more sound, ufo_hit.wav, was provided with the project. See if you can repeat the steps above to add the sound to your project and have it play whenever the UFO is hit by the player’s bullets. We won’t spend much more time focusing on sound, but you now have the basic tools to add any sounds you want to your games!

@rlangewi 43 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Conclusions There you have it, your first game in GameMaker! You learned a lot during this project, and it may still feel like too much information to remember. That’s alright! You can always reference back to this project if you forget how we made something work, and future projects will help to refresh you on many of the concepts we talked about here. But hopefully you feel like you have a basic understanding of how games are made in GameMaker, and some of the building blocks that you have to work with. Of course, there are plenty of things we could add to our game to make it more fun and interesting, but this is a good stopping point for purposes of this project. If you want to try to implement some additional features, check out the Going Further... section below that provides various challenges for you to try on your own. Great job making it this far, and hopefully you are excited to learn more about what you can do in GameMaker!

Going Further... If you made it to this point and still have time to spend on this project, see how many of the following challenges you can figure out how to implement!

Challenge #1: Force the Player to Stay on the Screen Right now, if you keep moving the player’s ship in one direction, you can just keep going off of the side of the screen forever! This is because nothing is telling obj_player that it should stop when it hits the edge of the screen. See if you can find an event and action that can be added to obj_player to fix this problem.

Challenge #2: Allow the Player to Move Up and Down We designed obj_player so that the spaceship would only move left and right. See if you can add controls to allow the player to move freely around the whole screen. Make sure that your solution to Challenge #1 doesn’t allow the player to move off the top or bottom of the screen either!

@rlangewi 44 www.ludolodge.com

Project 1: UFO Attack! Revision 1.00

Challenge #3: Randomly Change UFO’s Movement Speed While the UFO attacks are randomized and can surprise the player, the UFO’s movement is very predictable and constant, making it easier to stay out of the way of its attacks. Make a change so that whenever the UFO hits the side of the screen and reverses, it randomly picks a new speed anywhere from 8 to 20.

Challenge #4: Keep Track of High Score Right now, the game just restarts whenever the player gets hit. Let’s add a high score so that you can keep track of your best performance. The high score should be shown in the top-right corner of the screen (e.g. “High Score: 15000”) and it should be updated whenever the game ends and the player’s score is higher than the current high score. Don’t worry about the high score resetting when you close the game and reopen it; saving data to a file between games is a more advanced concept that we will cover later.

Challenge #5: Double Shot Powerup See if you can add a powerup that allows the player to shoot double bullets for a certain amount of time. There will be a random chance that the UFO drops the new powerup, and if the player touches it, they will fire out two bullets (side by side) at a time instead of one. The powerup should last for 10 seconds, and then the player should return to firing one bullet at a time as usual.

Find Errors in This Lesson? Please contact me at the following email so that I can make corrections and continue to improve the effectiveness of these teaching resources!

@rlangewi 45 www.ludolodge.com