Vacuum Marauders

V3.0

© 2008 PAUL KNICKERBOCKER FOR LANE COMMUNITY COLLEGE

In this game we will expand on our V2.0 model to include a scrolling background, more lives for the ship, the introduction of shooting enemies and smoothing out player movement.

This game will focus on:

  • Tracking and displaying lives
  • Background scrolling
  • Random conditionals
  • Keyboard events
  • Variables

1.Background scrolling

This is one of the easiest modifications to make. Open “room_main” and go to the “Backgrounds” tab. At the bottom of the window there are two boxes, Hor. Speed and Vert. Speed. These boxes control the speed at which the background scrolls vertically and horizontally (0 being no scrolling at all). Set Vert. Speed= 3:

Test the game and see how the scrolling background gives the impression of movement.

2.Smoothing Player movement

During the course of testing the game you probably noticed that the player’s movement can be somewhat jerky and imprecise. This is because while our movement system is simple, there are better ways of getting the same result by doing the movement manually.

Start off by removing both the Key Press <left>, Key Press <right>, Key Release <left> and Key Release <right> from “object_player” by using the button underneath the event list.

Add in a event for <left>. The difference between Keyboard and Key Press is that Keyboard executes on every step when the button is pressed down, Key Press only executes once when the key was initially pressed. Add a Jump to Position action (, in move tab) with X = -5, Y = 0 and Relative checked:

What Jump to Position does ismove the object instantly to a new (X,Y) position on the screen. Remember that Relative means that the coordinate system is centered on the object so the new position we are moving to (-5,0) is in fact just 5 pixels to the left of where we are now. Because we are moving a small amount several times a second the action seems fluid. The Keyboard event automatically starts and stops movement by only executing the jump when the key is pressed down.

That handles movement left, now repeat the process for <right> only this time make the aJump to Position action () have the parameter X = 5 (which is 5 pixels to the right of the object).

Now test the game and see how much smoother the motion is:

OH NO!!!! – Our motion may be smoother but we are falling out of the room again. This is because by doing the motion “manually” and not using Move Fixed the object never has any speed. Our Intersect Boundary event is still going off but it has no effect because to the object is ALWAYS at a dead stop.To fix this we will have to “manually”control whether or not we execute the Jump to Position inside of the Keyboard event.

When we look at the screen as a coordinate system we see that the edges of the room are defined by X = 0 and X = 480:

So if we can restrict the keyboard event so that the Jumpto Position only occurs when the X value of our ship is greater than 0 but less than 480 ( 0 < X < 480) we would have a solution. Luckily, Game Maker supplies us with Variables.

Variables are special words defined in Game Maker that stand in for a value that may change or won’t be known till the program executes. “score” is a good example of a variable: you can use the word “score” in any Game Maker action and when the action is actually run during the game, Game Maker will replace the word “score” with the player’s current score. Variables are indispensable if you want to work with values in the game that change over time.

Two very helpful variables are “x” and “y”. These represent the exact X and Y coordinates of the object. Whenever “x” and “y” are used in an action, they are replaced by the real coordinates of the object while the game is running. If we want to see if the X coordinate of the object is greater than 0 or less then 480, the variable “x” will tell us.

In the Keyboard <left> event, add a Test Variable conditional (, in the control tab) and set Variable = x, Value = 20 and Operation = larger than:

This conditional will test the X coordinate of our object (the “x” variable) to make sure it is larger then 20, and if so perform a Jump to Position action. Why 20 and not 0? Our “x” variable is in the CENTER of our object so when X = 0, half the object will be out of the room by then so 20 gives us some buffer space.

Make sure the blocks are put in correctly so you have this:

Repeat this process for Keyboard <right only for the Test Variable use Variable = x, Value = room_width – 20, and Operation = smaller than:

We use another variable in this conditional: “room_width”. This is automatically set to the size of the current room (and also its maximum X value), in this case 480. Again we take 20 off the value to make sure our ship doesn’t spill out of the room.

Why use “room_width”, why not just use 480? If we put in 480 and then changed the room size we would have to go back and find all the actions we used 480 in and change it. What if we wanted to change the size during the game? Hard coding in numbers you assume to be constant is a very bad programming practice (Hard coded numbers are often derisively called “magic numbers”). Use variables whenever possible.

Test the game and you should have a smooth moving ship that stays inside the room.

3.Adding Extra Lives

While our game is fun, it is also very unforgiving. The addition of additional lives should balance out the gameplay.

Like score, the value of lives is set to 0 by default, so the first thing we will want to do is set the number of lives. Being a game-wide attribute, we will handle it in the controller object. Open “object_controler” and add a Game Start event (which is found under). The Game Start event happens only once when the game starts, we will set the lives here because if we used Create or Room Start, the lives would be reset each time the player destroyed all the enemies and the room restarted. Be careful using the Game Start event because if the object that calls it wasn’t placed in the first room before the game began it will never be triggered.

Inside of Game Start put the Set Lives action (, in the score tab) with New Lives = 3 and Relative unchecked:

This sets the number of lives at the beginning of the game to 3. Lives is also a variable that can be accessed by the “lives” word.

Now that we have set the number of lives, we will change the game behavior to use them. Open up the “object_exp_player” and look at the Animation End event.Right now when the player’s explosion gets through it ends the game. What we want to do is remove the Restart Game action and Show Highscore, then put in a Set Lives action () with New Lives = -1 and Relative checked:

This decreases the number of current lives by 1 and is effectively equal to score = score -1. We will also need to create a new player object after this so put in a Create Object action () with Object = “object_player”, X=0, Y=0 and Relative checked:

Make sure that all this happens BEFORE the Destroy Instanceaction (), otherwise it may never happen:

Now that we can take lives away, we need to make sure that we are using lives to determine when to stop the game. We might as well check the number of lives in the same place we checked if there were any enemies left – the Controller object’s Step event.

Below the block where we check the number of enemies, add a Test Lives conditional (, in the score tab) with Value = 0 and Operation = Equal toand add in the necessary start and end blocks:

Within the start and end blocks add in a Show Highscore () and Restart Game () so that you have:

You can now test the game to make sure that the ship will blow 3 times before the highscore shows up.

4.displaying lives

While we have the lives up and running, we never tell the player how many lives they actually have. Game Maker allows us an easy way to display the lives with sprites, but first we are going to have to make a smaller version of the ship sprite.

First, make a duplicate of “sprite_player”:

Name this one “sprite_player_lives”. You should have an exact duplicate of the sprite that we can use to make our life sprites. Click on the button inside the sprite, this will bring up the sprite editing application within Game Maker.

While there are a lot of cool tools for editing and animating sprites in the editor, all we want to do now is scale down the image. Select Transform then Stretch from the menu:

Keep the Keep Aspect Ratio box checked and change the width to 20 pixels, the height should automatically adjust:

after that hit OK till you get all the way back to the sprite. Make sure you hit the button one more time to line the image back up then exit the sprite.

Now that we have a smaller ship we can draw it onto the screen. Just like writing the score, the drawing of lives will be handled in the Draw event of the controller object. At the end of the current actions in draw, add in a Set Color action (, in the draw tab) where you set the color to a shade of green. Then add in a Draw Text action (, in the draw tab) with Text = “Lives:”,X = 300 and Y = 30.

This action just draws some text to the screen at some location. The Draw Score action had this built in but for lives we have to do it ourselves. Next up, put in a Draw Life Images action (, in the score tab) with X = 360, Y = 40 and Image = “sprite_player_lives”.

We adjust the Y coordinate down 10 pixels to line it up better. Alignment for drawn images is often done through trial and error. The end result should look like:

Now we should have a game that displays life images right after the score:

5.enemies that shoot back

While our enemies can kill the player through collision, they still don’t pose much of a threat. So first we will give bullets for the enemies to shoot back at the player. If you haven’t already loaded fireball sprites, do so now.

Make a new object “object_fireball” and give it a fireball sprite:

Just like the missile we made for the player, we will start off the fireball moving. Add a Create event and add in a Move Fixed action () where Speed = 8 and the arrow is facing down:

We will also need to handle what happens when 1) the fireball collides with a missile, and 2) the fireball collides with the player. To handle collision with a missile, add in a Collision event for “object_shot” and fill it with a Create Instance () with Object = “object_exp”, X=0, Y=0, and Relative turned on. Follow up with two Destroy Instance actions () that are applied to Other and Self, in that order. Now the fireballs should explode when they hit a missile.

To make the collision with the player we will use another time saver, the Duplicate Event. Right-click on the newly created Collision event for the missile and choose Duplicate Event:

From here it will pull up the event selection box, choose a Collision event for “object_player”. This will make an exact copy of the actions into the new event. Now go into the new Collision and change the Create Instance so that Object = “object_exp_player”:

Now we have a collision that uses the player’s special explosion.

Now to the process of getting the enemies to shoot; we could have them shoot on a regular interval but that could be a little bland. Instead, we will have them shoot randomly by using the Test Chance conditional (, in the control tab). Test Chance is a conditional that performs its actions unpredictably; it uses the computers pseudo-random number generator to roll an imaginary dice with a specific number of sides (dictated in the action parameters), one of those “sides” is the “yes” side that makes the conditional execute its block of actions. You can control the frequency of when things happen by adjust the number of “sides” (ex. 60 sides means that the block of actions will run 1 time out of 60 times running the conditional), but the exact timing of the action is random.

In our case we will use Test Chance () inside the Step event for the enemies to make them shoot randomly. Open “object_enemy” (again, because of inheritance this will apply to all enemies) and add a event. Inside Step, put the Test Chance()conditional with Sides = 60:

The NOT box will execute the block if the magic side is not hit, which means that it would shoot 59 times out of 60 tries.

In this game we have around 30 steps per second (a number controlled by the Speed setting in “room_main” under the settings tab – adjust this to speed up or slow down the game), so the enemies are set to fire about once every 2 seconds.

Put in the necessary blocking under Test Chance and add a Create Instance () action inside the blocks with Object = “object_fireball”, X=0, Y=0 and Relative turned on. You should have:

For good housekeeping, add an Outside Room event with a Destroy Instance () action applied to Self in it.

Now test the game and make sure that the bullets get shot and hurt the player:

Just for fun (and demonstrate some new features) we will make another type of fireball and have one of the enemies shoot that instead. Create a new object “object_fireball_seek”, give it a distinct fireball sprite and set Parent= “object_fireball”:

The magic of inheritance will give us all the collision actions, all need to define is a new Create event (Overriding the parents Create). Create a new Create event in the new fireball and this time put in a Move Towards action (, in move tab) with Speed = 6 (we slow it down to make it easier to dodge), X = “object_player.x”, Y=”object_player.y” and Relative turned off:

Move Towards sets the movement path of the instance to some fixed point of the screen at some speed, here it is towards the player’s ship. This demonstrates another way to use variables – if I want to access a specific object’s variables I just put in the name of the object, then a “.”, then the name of the variables. in this case, “object_player.x” is the “x” variable for the “object_player” that is on the screen. Be careful, if there was more then one instance of “object_player” in the room this wouldn’t work.

Now that we have a seeker fireball, we need to have some enemy fire it; again we will try to save some time. Open the “object_enemy” and select the Step event we just created, highlight all the actions, right-click and select Copy:

Just like text and pictures in Microsoft Word, you can cut and paste actions in Game Maker.

Now open “object_enemy3” and add in a Step event (this will overridethe Step event we made in it’s parent. Now right-click in the action field and select Paste. This should give you a duplicate of the actions from “object_enemy”:

Now change the Create Instance () so that Object = “object_fireball_seek”:

Now if you run the game your enemy3 guys should shoot seeker missiles at you:

OH NO!!!! If while testing you get hit, you will notice that the following error sometimes pops up:

You can see it tells you exactly in what event the error happens(Create of “object_fireball_seek”) and what the error was (Unknown variable “object_player.x”). In this case it is looking for the variable “x” in the instance of “object_player” and came up short. This is because after the player is hit there is no instance of “object_player” in the room. If there is no instance, how could it have aX coordinate if it doesn’t exist? When a fireball_seek gets created while the player’s explosion is happening it has no player to home in on so it throws an error.

To fix this error we will just add in another conditional, a Test Instance Count () that will check to make sure there is a player to seek before we make a fireball. Inside Test Instance Count put Object = “object_player”, number = 0 and Operation = Larger then (only execute block if there are more then 0 players):

Now add the blocking so that the Create Instance is inside Test Instance Count, which is inside of Test Chance: