In this game we will expand on our V2.0 model to include a scrolling

VACUUM MARAUDERS
V3.0
© 2008 PAUL KNICKERBOCKER FOR LANE COMMU NITY 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
event list.
button underneath the
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 (
move tab) with X = -5, Y = 0 and Relative checked:
, in
What Jump to Position does is move 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
time make the a Jump to Position action (
to the right of the object).
<right> only this
) have the parameter X = 5 (which is 5 pixels
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:
X=0
X = 480
So if we can restrict the keyboard event so that the Jump to 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 (
set Variable = x, Value = 20 and Operation = larger than:
, in the control tab) and
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 (
Relative unchecked:
, in the score tab) with New Lives = 3 and
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 (
and Relative checked:
) with New Lives = -1
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 Instance action (
never happen:
), otherwise it may
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 to and add in the necessary start and
end blocks:
Within the start and end blocks add in a Show Highscore (
that you have:
) and Restart Game (
) so
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
will bring up the sprite editing application within Game Maker.
button inside the sprite, this
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 (
Text = “Lives:”, X = 300 and Y = 30.
, in the draw tab) with
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 (
down:
) where Speed = 8 and the arrow is facing
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
conditional with Sides = 60:
event. Inside Step, put the Test Chance(
)
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 (
applied to Self in it.
Now test the game and make sure that the bullets get shot and hurt the player:
) action
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 override the 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 a X 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:
Now seekers will only be created if the chance number comes up AND there is a player to
shoot at. The error message should now go away.
FINISHING UP
Now we should have the following new features implemented:




A scrolling background
Smoother player movement that is based on jump commands
Multiple player lives and life icons
Shooting enemies