PacMan Tutorial
PacMan Tutorial
PacMan Tutorial
The game made in this tutorial was created using Game Maker 7.0 Pro. Any version after 7.0 should work just as well.
This tutorial also works with the Lite versions of Game Maker.
Introduction
In this tutorial you will be making the ever so popular game known as PacMan. You'll be using the sprites that
come with the Game Maker 7.0 package. You may feel free to use any sprites you desire just make sure that
you can follow along.
While creating this game we'll also be discussing the idea of the game and the mechanics behind it. We'll be
discussing what aspects of the game keep the player playing and what may cause the player to stop.
The game will be created with Game Maker's built in scripting language -Game Maker Language- (GML) and
as such it is recommended that you already have a thorough understanding of Drag and Drop and the logic
behind Game Maker itself.
For the sake of simplicity, this tutorial comes with two folders. One contains several GMK's of the game we'll
be creating in case you need some guidance and the other folder contains the sprites and sounds that come
with Game Maker which we'll be using.
You'll also be learning how to polish this PacMan game to make it as presentable and smooth as possible.
That will be at the end of the tutorial.
So, open up Game Maker, take a deep breath, maybe go drink some water, and enjoy.
Game Idea
Usually, when someone wants to create a game, they have the idea written down and well documented. It's
good practice. However, for the purposes of this tutorial the game idea has been simplified below:
The player takes control of the character PacMan and must maneuver his/her way through the current maze
avoiding ghosts (enemies) and collecting points (dots). The player may 'eat' certain special pellets that make
the enemies vulnerable. The player must devour all of the points in a level to move onto the next level. If there
are no more levels after the current one then the player will be presented with a congratulatory message and
will be rewarded and given the option to play again.
It's not the best description in the world but it should suffice. Now, time to make it all happen.
Creating Movement
In this section we'll be adding some sprites and then we'll be assigning those sprites to the objects that will
make the magic happen.
Let's create some sprites. We'll need all of the directions that PacMan faces and a wall sprite.
Do the following:
Repeat steps 1-4 for sprites pacman_down.gif, pacman_up.gif, pacman_left.gif, pacman_right.gif, and wall.gif.
Name the sprites spr_pacdown, spr_pacup, spr_pacleft, spr_pacright, and spr_wall respectively.
Now that we've created the sprites. Let's get down to the actual movement.
When thinking about PacMan's movement, there's a lot more to consider than just if the player has pressed a
key. PacMan has to know if where he's about to move is collision free, he also has to know if he's aligned with
the grid so that he won't move too freely in completely open spaces. After checking if movement is possible,
PacMan has a few actions that he must execute.
PacMan has to pick the correct direction in which to move and the correct sprite to display, PacMan has to set
the proper speed and then finally, PacMan should select an appropriate image_speed. So, let's get to it.
Let's create two objects. First, let's create the PacMan object.
Create a Keyboard Left Event and then in the Control tab, select the Execute Code action.
Open Block
Is the area 32 pixels to the left free?
Are we snapped to the grid of 32x32 pixels?
Open Block //If we are, the following will execute
Set my direction to 180 (left)
Set my speed to 2 pixels per step
Set my sprite to spr_pacleft
Set my animation speed to 1/4
Close Block
Close Block
That's exactly what the code is doing. It checks if there's nothing in the way in which it wants to travel and it
checks if it's snapped to its grid. If all of these requirements are met, then the object executes its actions.
By now I'm sure you've noticed that only small changes had to be made to the original code. Values to choose
the proper direction and simple sprite name changes. Copy and Paste is your friend.
Now, let's make one more simple script. We'll be placing this one in the Create Event. So, make a Create
Event and add the following:
Create Event for obj_pacman
{
image_speed = 1/4;
}
This small script sets the initial image_speed to 1/4. We place this here because spr_pacstand is an animated
sprite and we don't want the animation to play too quickly.
We've added movement to our PacMan but it is not complete. However, create a room and place PacMan in
the room somewhere snapped to the 32x32 grid. Test your game.
You'll notice that PacMan moves slowly. This is because the room speed is set to 30. Every programmed value
right now (such as speed and image_speed) would look much better if the room speed was set to 60. So, open
up your newly created room, go to the Settings tab, and set the room speed to 60.
Now if you run your game you'll see that PacMan moves smoothly.
We have yet to add any walls to the room. If we did, PacMan would go straight through them. Our movement
engine is still incomplete so let's finish it up.
To finish the movement there's only one simple thing to add. We need to make obj_pacman check for a
collision with obj_wall. If they collide we stop obj_pacman from moving, we snap obj_pacman to our 32x32 grid
(just in case), and we set the proper sprite.
Alright! The movement is now complete! You may add some wall objects to your room and test PacMan's
movement. If there's anything that's not working properly then retrace your steps to see if you made any
mistakes. You can find an example with all of the progress so far in the Examples folder under the name
pac1.gmk.
Enemy
So now we have a PacMan that moves smoothly around the room and we have some nice walls. Doesn't
sound very fun just yet. There's no objective and there are no obstacles. So, let's add the ever so popular
ghosts! These little guys will randomly move around the room causing the player to be more cautious when
making decisions.
Go ahead and make a ghost sprite. Choose from any of the monster.gif sprites that you see around. Only
make one sprite and call it spr_ghost.
Now, create a new object and call it obj_ghost. Remember to give it the spr_ghost sprite.
So, let's think. What do we want our ghost to do? Before our ghost does anything at all, it needs to choose a
direction to move in and then actually move in that direction. We want the direction to be random between four
choices: 0 (right), 90 (up), 180 (left), or 270 (down). Luckily, there's a function that does the work for us.
We can use the choose() function. The choose() function chooses one of the values within the parenthesis.
You can have up to 16 arguments.
So, let's set this up. Open up your ghost object and make a Create Event. Place an Execute Code action and
write in the following:
As you can see, the first line of code sets the object's speed to 2. The second line of code uses the choose()
function with four arguments (the four desired directions in this case). One of those directions will be chosen
and assigned to the variable direction.
Our ghost object will now move as soon as the level begins. Now we just need to make it move randomly
throughout the level so as to provide a challenge for our player. When obj_ghost comes across a possible
intersection, we'll make it have a random chance of changing its direction. If the random chance ends up as
false then our ghost will just continue on its way.
Let's create a script. Click on Resources and then click on Create Script. In the newly opened code editor,
name the script scr_orient, and put the following:
scr_orient
{
if (hspeed == 0)
{
if (random(3)<1 && place_free(x-32,y))
{
hspeed = -2;
vspeed = 0;
}
if (random(3)<1 && place_free(x+32,y))
{
hspeed = 2;
vspeed = 0;
}
}
else
{
if (random(3)<1 && place_free(x,y-32))
{
hspeed = 0;
vspeed = -2;
}
if (random(3)<1 && place_free(x,y+32))
{
hspeed = 0;
vspeed = 2;
}
}
}
First it checks if the hspeed (the horizontal speed) of obj_ghost is 0. If it is then the ghost must be moving
vertically since it can't stand still. Next, it uses the random() function. This function picks a random value
between 0 and the number entered (in this case 3) not including the number entered (so between 0 and 2).
The expression is asking if random(3)<1, this gives us a 1 in 3 chance of it turning out true. If it turns out true
then it checks if there's free space to the left. If both of these are true then hspeed is set to -2 (meaning the
ghost will move left) and vspeed is set to 0 to cease vertical movement.
The rest of the code is similar but checks for the right (if moving vertically) and then checks up and down if the
ghost object is moving horizontally.
Let's close the code editor and open up obj_ghost. We want this script to be executed every time that
obj_ghost is aligned to the grid (wouldn't want him changing direction halfway through the grid square). Make a
Step Event. Set an Execute Code action and write the following:
In this bit of code, we simply run a check every step (60 steps per second). In every step, we check if the
object is aligned to the grid. When and only when the object is aligned to the grid of 32x32 do we execute our
previously created script. To execute our script, you simply have to write down the name of said script and
place () after it.
Just one more bit of code needs to be added to our ghost. We need to establish what happens when our ghost
collides with a wall. Before the ghost hits the wall, our code in the Step event will execute. If the ghost decides
to not change direction but instead go into the wall, then we'll just make him turn around. Create a Collision
Event and choose obj_wall. Place an Execute Code action and write the following:
Pretty simple. We're just adding 180 to whatever the direction currently is. This will make the ghost go in the
opposite direction.
Right now, our ghost will just wander around the maze. It doesn't pose any threat to the player. For now, let's
open up obj_pacman and set a Collision Event with obj_ghost. Set the Execute Code action and write:
It's simple. That's all we'll use for now. Later we'll open this part up again and do a multitude of other things.
Right now, as it stands, we have our PacMan, walls, and our enemy. If the enemy collides with PacMan then
the game is reset. Go ahead and make a small maze. Place some ghosts in it and a single PacMan object and
then test it.
Should anything go wrong just check to see if you made any mistakes. You can open up pac2.gmk in the
Examples folder to see the work as it should be up to this point.
The Objective
We have PacMan, we have walls, we have ghosts, so what's missing? Our objective. What is it that PacMan
has to do in every level to get to the next level? He has to eat all of those tiny dots that are in the maze! So, in
this section we will be making those little dots. It's not much to do. In fact, you'll think this section is ridiculously
short but you'll see towards the end of this tutorial that a lot is going to be added. For now, we just need these
dots.
So, what do these dots do? They give points, yes, but they have a bigger role. Once they're all gone, they lead
the player to the next level and eventually to the ever satisfying victory!
First, create a sprite and load up dot.gif in the Resouces > sprites folder. Name the sprite spr_point. Now
create a new object, assign it the spr_point sprite, and name it obj_point.
You may now close obj_point as the actions will be executed by obj_pacman. Open up obj_pacman and create
a Collision Event with obj_point. Execute some code and write the following out:
Let's see what this code does. The first thing we see is a with (other) instance_destroy(). with (other)
means that whatever is written after the last parenthesis will affect the object within the parenthesis. In a
Collision Event, other refers to the other object involved in the collision. In this case, the other object is
obj_point and we're destroying it with instance_destroy(). Afterwards, we have an if statement. The if
statement is checking if there is no more of obj_point left in the room. If there still are objects left then nothing
happens, however, if the statement is true, then the rest of the code is executed. Assuming there are no points
left, next we check if we're at the last room. If we are not then that means that there are more levels so we go
to the next room with room_goto_next(). If there are no more rooms after the current one then this must be
the last level and it means that you won so the else is executed. We show a congratulatory message and we
restart the game.
That seems like a pretty dull ending and it really is but don't worry, we'll spruce it up later. Make a second
room, fill it with some walls and some points, add PacMan in there and close the room. Open up your previous
room and add some points. Test your game and make sure that after eating all of the points in the first room,
you advance to the second. Then make sure that after eating the points in the second room, you get your
congratulatory screen.
You can find the current version of the game in the Examples folder saved as pac3.gmk.
Vulnerable Enemies
In a game, if you cannot defeat your enemies at all then odds are that you won't be too interested in playing
since your enemy will always have the upper hand. In the original PacMan, the ghosts could become
vulnerable after eating a special pellet. In this PacMan game, we're going to add the exact same system.
Not only does this make our player feel more powerful, it also grants our player choices. Eat the enemies for
bonus points but then they come back faster, or salvage this precious time to eat as many dots as possible.
What are we going to be doing? We are going to add two sprites. The special pellet sprite and the vulnerable
ghost sprite. Then, we're going to make their objects. The special object will simply turn all of the ghosts into
their vulnerable forms for a certain amount of steps. The vulnerable ghost object will act exactly as the ghost
object except that it cannot harm the player. If eaten, it'll jump back to its original starting position but become a
threat once again.
So, create a new sprite. Load up scared.gif from the Resources > sprites folder. Name it spr_vulnerable. Now
create another sprite. Load up special.gif and name it spr_special. Create two objects, give one the
spr_vulnerable sprite and name it obj_vulnerable and give the other the spr_special sprite and name it
obj_special.
We're not going to add anything to obj_special since the actions will be executed by obj_pacman.
Open up obj_vulnerable. Where it says parent, set the parent to obj_ghost. By setting obj_vulnerable's parent
to obj_ghost, you're telling obj_vulnerable to do everything obj_ghost does unless otherwise specified. Close
obj_vulnerable.
Go ahead and open up obj_pacman. Create a Collision Event with obj_special and set an Execute Code
action. Write the following in the code editor:
Once again we use with. You're familiar with the first with as it does the same thing that it did the first time we
used it. It destroys the other object involved in the collision which in this case is obj_special. The second with
is directed at obj_ghost. When a with statement is directed at an object, it doesn't target any specific instance
of that object. Instead it targets all instances of that object. The second with is telling all instances of obj_ghost
to change into obj_vulnerable. The third with statement is directed at all instances of obj_vulnerable (which all
instances of obj_ghost just became) and it sets all of their alarms to 300 steps. At 60 steps per second, that's 5
seconds. We'll decide what happens at that alarm shortly.
We used an instance_change() function. This function has two arguments. The first argument asks what
object the current object is changing into. The second argument asks whether or not we want to perform the
Create and Destroy events. We don't really have a Create event in obj_vulnerable and setting this to true
would be unnecessary, so we set it to false.
Now, let's open up obj_vulnerable. In obj_pacman's collision with obj_special we had set obj_vulnerable's
alarm to 300. We're going to now set what happens. Create an Alarm0 Event and set an Execute Code action.
Write the following:
Alarm0 Event for obj_vulnerable
{
instance_change(obj_ghost,false);
}
Pretty simple. At the end of the 5 seconds, we want all instances of obj_vulnerable to switch back to obj_ghost.
If you'll look at the function, you'll see that we set the second argument to false again. This time the reasoning
is a bit different. In obj_ghost's Create Event, it selects a random direction to move in. If this event were
performed then it would look odd since the second that obj_vulnerable changes to obj_ghost it might change
direction. We set it to false which stops the Create Event in obj_ghost from being executed.
Now, obj_vulnerable has obj_ghost set as a parent. If PacMan collides with obj_vulnerable then the Collision
Event that is set with obj_ghost will run, thus restarting the game. We don't want that so we're going to specify
a collision with obj_vulnerable. This will override the collision with obj_ghost when colliding with obj_vulnerable.
Open up obj_pacman and set a Collision Event with obj_vulnerable. Set an Execute Code action and write the
following in the code editor:
In this code we have a with statement. The with statement specifies that the actions within the curly brackets
will run as if obj_vulnerable was executing them. First we see x = xstart. Since this code is being executed
as if obj_vulnerable were executing it, everything written in it will affect obj_vulnerable. x = xstart will set
obj_vulnerable's x position to the x position it had in the beginning of the level. Since obj_vulnerable was first
obj_ghost and all instance_change() functions had been set to false, obj_vulnerable's first x position was
wherever obj_ghost had started. Same goes for y = ystart. We now have yet another instance_change()
function but this one is set to true. The reason for this is because this time obj_vulnerable is being sent back to
where it started. This time we want obj_ghost's Create Event to execute so that a random direction will be
chosen.
Open up the first room and place a few instances of obj_special at a nearby distance. Test the room and make
sure that the ghosts stay vulnerable for 5 seconds. Make sure that when you collide with them they go back to
their initial position. Make sure that there are no bugs and that everything works properly.
You can find the current version of the game in the Examples folder saved as pac4.gmk.
What's Next?
Well, technically we are done. There's the player, the movement, the obstacles, the powerups, and the main
objective, but let's face it, how the game currently stands, even you would most likely not play it. PacMan has
one life (because as soon as he collides with obj_ghost the game restarts), there's no thrill, no real ending
(other than a box that says "congratulations" ... yay...), nothing shiny, and nothing to give the game life. We
simply have the core of the game.
So, in the following sections we are going to work towards giving this PacMan game some life. We're going to
add a few more aspects and then we're going to polish it.
Scores
Alright! Nothing makes a player feel like they're being rewarded for their actions like a nice score! Except
maybe giving PacMan an atomic laser gun, but let's not do that. In this section, we are going to create a
scoring system. Everything that PacMan does that's good we shall reward with points. However, we shall not
take away points if he messes up. If PacMan were to collide with a ghost and lose points... well... I'd be pretty
angry if I was the player. Losing a life (well, as of right now, the game restarting) is punishment enough. Points
are good things used to reward good things. In this game, anyway.
So, let's create our first ever control object. A control object has no sprite. It's simply an object that's there to
either keep track of certain variables or to set something or etc. In this case, our control object will simply set
the score to 0. We'll be placing this object in only the first room. We wouldn't want the score being set to 0
every level, would we?
The variable score is a built-in Game Maker variable. It isn't "noobish" to use the tools that you have been
provided with so that's exactly what we're going to use. The score variable is already global (which means that
once it's set it goes throughout the game and can be changed whenever by any object).
Let's think of some questions to ask ourselves. Should the player earn 500 points every time he/she does
something good? No. That would make the reward for everything exactly the same and the player wouldn't see
the point (no pun intended) in eating ghosts (since they'd usually be worth a nice amount) over just eating
points.
There's some questions we need to ask ourselves. When does the player earn points? How many points
should the player earn for doing a specific good thing? Let's establish these.
The player should earn points when eating vulnerable ghosts. The player should also earn points when eating
the special objects. Finally, the player should earn points for eating... well... points (obj_point).
How many points should the player earn? Well, let's place things in order of how common they are.
>Vulnerable Ghosts - Usually there's only 3 - 5 per level and they aren't always vulnerable.
>Special Objects - Usually around 6 - 8 per level and they're always accessible.
>Points - These are everywhere.
In that list, the object closest to the top is the rarest and therefor should be worth the most. I have a little list but
feel free to mess with the values.
Great! Enough reading and theorizing. Let's get down to business. Create a new object, this object has no
sprite, and name it obj_control_start. Give this object a Create Event and set the Execute Code action. In the
code editor write the following:
Create Event for obj_control_start
{
score = 0;
show_score = true;
}
This is some very easy code. First we set the variable score to 0. Then, we set the variable show_score to
true. The variable show_score is also a built-in variable. If set to true the current score will be displayed on the
title bar up top (we do want our player to know their score).
Close obj_control_start and open up obj_pacman. Now, go to the Collision Event with obj_point and open up
the script that's already there. We're going to add score += 10 to it. Here's what the new script should look like:
We've now added 10 to our score (+= is an assignment operator. It adds to the previous score. score =
score + 1 would work as well). Now lets edit our collision with obj_special and obj_vulnerable.
We have the scores now and if you'd test the game you'd see the score increment accordingly up top, but we
need to show the player their final score should they die or win. If they die, we bring up a nice score-board and
let them add their score to that list. If they win the game then we want to reward them for having beaten the
game (a nice big bonus of 100,000 points) and then we'll show them their score and allow them to enter their
names to the list.
Game Maker has a convenient function for showing the highscore table (lucky us) that we'll be using. Let's
make this happen.
Open up obj_pacman and go to the Collision Event with obj_ghost. When obj_pacman collides with obj_ghost
the game resets because he dies. We want the player to know their score and how well they did compared to
other times when they die. Open up the script that's there and edit it so it reads as such:
As you can see, all we added was highscore_show(). The function highscore_show() shows the highscore
in a highscore table and adds the number placed within the ( and ). In this case, we placed the variable score
within the parenthesis which gives highscore_show() the value of the current score.
Now, go to the Collision Event with obj_point. This is the object that decides whether or not you won depending
on how many of that object there are left in the room and whether or not there's a room afterwards. Open up
the script and edit it as such:
Here we give the player a nice 100,000 point bonus for having beaten the game and then we show the current
score.
We now have a nice score system. If you were to test your game now you'd see that the scores are set at the
right times and that you get a nice highscore table when you win and lose. Before closing this section off, let's
add one more object to our game.
This object's sole purpose is to give the player points. It's an object that there usually wouldn't be a lot of in a
level. Sometimes only one would be available. It's also an object that isn't always accessible by the player.
Those characteristics would make this object the rarest one and therefor the most valuable. We'll be giving it a
value of 800 points.
This object will not be in the room when the level starts. After 10 seconds, the object will appear in the room.
Then, after 5 seconds, the object will leave the room again. It will do this continuously until eaten by the
character.
Make a new sprite. Load the image bonus.gif and give it the name spr_bonus. Create a new object, name it
obj_bonus and give it the spr_bonus sprite.
Give obj_bonus a Create Event. Place an Execute Code action and write the following:
The Create Event occurs before the player can even see the screen. Setting obj_bonus' x value to 1000 will
place it out of the room making access to it impossible by the player. We also set this object's alarm to 600
(600/60 = 10) which means 10 seconds.
We want the object to come back into the room after the 10 seconds are up. Create an Alarm0 Event and
Execute the following code:
After the 10 seconds are finally up we set obj_bonus' x back to where it started. This makes the object
accessible. We also set alarm 1 to 300 (300/60 = 5) which is 5 seconds. After these 5 seconds we want
obj_bonus to go back into hiding. Create an Alarm1 Event and Execute the following code:
This sets obj_bonus' x position back to 1000 so that it's once again out of reach. Then it sets alarm0 to 10
seconds. These two alarms will continuously loop.
Open up obj_pacman and create a Collision Event with obj_bonus. Set the Execute Code actions and write the
following:
This code adds 800 to the player's current score and destroys the bonus object.
Place obj_control_start in the room. Place a few of these bonus objects and test out that they work. Also test
the entire score system and make sure that it all works. If there were any mistakes then you can either try to fix
them or just check the saved file with all of the current progress. The file can be found in the Examples folder
saved as pac5.gmk.
Lives
As it stands right now, if you had 10 levels of PacMan, there's a very high chance that most players wouldn't
make it past the third level. Why? As soon as PacMan comes in contact with a ghost it's game over. We need
to fix this and we need to fix this now. Lives give a player time to reflect on what they did wrong last time, fix it,
and try again.
Open up obj_control_start and edit the script in the Create Event so it reads as such:
We added two new lines of code. Just like how score is a built in variable, lives is one as well. We just set it to
three. You can probably guess what show_lives does. It acts in the same exact way as show_score. It displays
the lives on the title bar.
Open up obj_pacman and open the script in the Collision Event with obj_ghost. Delete everything that's written
in this script and replace it with this:
I know this script is much larger but it is necessary. What does this script do? First off, it subtracts one of the
player's lives. Then it sets the player's x and y coordinates back to what they were at the beginning of the level.
They set the player's speed to 0 and the sprite to spr_pacstand. It makes all instances of obj_vulnerable
become obj_ghost and then it makes all instances of obj_ghost go back to their starting position.
Basically, we're moving everything to where it once was. The reason we don't simply restart the room is
because it would be frustrating for the player to have to eat all of the points again (as they would have been
reset as well).
Create a new object. Name it obj_control. This new control object is going to keep track of how many lives the
player has. If the player runs out of lives then certain codes must be executed. Make sure that you place this
object in every room as it is needed to check whether or not the player lost.
Make a No More Lives Event for this object. No More Lives can be found under Other. Place an Execute Code
action and place this in the code editor:
Place obj_control in your rooms and test out if it works. Make sure that when PacMan dies everything goes
back to where it was. Make sure that obj_vulnerable turns back to obj_ghost. If you made a mistake and need
the example, it's in the Examples folder saved as pac6.gmk.
So, let's start off by getting rid of that gray background. Click on Resources and select Create Background.
Load sky.gif and name it bg_sky. Open up your rooms and click on the backgrounds tab. In the box where it
says No Background, click it and select your new background.
Looks a lot nicer now, right? And all we did was add a background!
Our next step is to display our score and lives in a nicer location than on the title bar. Let's get rid of the display
on the title bar. Open up obj_control_start and edit the code in the Create Event so that it looks like so:
We just changed the values to false so that they won't be displayed. So, where do we want these displayed?
This ties in with our level creation. We want nice mazes that look organized and the default room size of
640x480 is just not going to cut it. Instead, let's make the room size more square-like.
Open up your room. Hit the settings tab. In width enter 480 and in height enter 512. Now our room is slightly
longer than it is wide. We'll be using a perfect square for level creation and we'll save the bottom row to display
our lives and score. (When re-sizing the room, you may want to delete everything before doing so).
Great. Now we need to use an object that will draw the values that we want displayed. Before doing that, let's
create a nice font for this. Click on Resources and then click on Create Font. Name it fnt_score and select
Comic Sans MS as the font (or anything else that you want) and then set the size to 16. Close the font window.
In all of our rooms we will have obj_control checking if PacMan has died. However, obj_control can also be
used to draw our lives and score. Open up obj_control and create a Draw Event. Set an Execute Code action
and enter the following:
In this script, our first line sets the color that we'll be using for our font. Then, we set the actual font itself. After
that, we tell Game Maker to draw a certain text. This text will show the string "Score:" and with the operator '+'
we're telling Game Maker to add what follows to the string. Since the variable score is not a string, we convert
it to one with the function string(). We just do the same on the next line for the lives. The first two arguments in
draw_text() are just the coordinates. I've already set them for you. (draw_set_halign() simply tells Game
Maker how to align the text).
Let's add something just to make things look nicer. Create a new background and name it tl_black. Load the
sprite black.bmp. Check "Use as tile set" and set the tile width and height to 32. Enter your room and use that
tile to cover the bottom where the score and lives will be displayed.
Now, let's add some sounds. I'm going to let you figure this one out. In the Resources folder you have the
sounds folder. In there are all of the sounds that you can use. The function for setting sounds is sound_play().
To make a sound loop use sound_loop() instead. Within the () put the name of your desired sound. For
example: sound_play(snd_beep). So, go ahead and load in your sounds and set them where you want!
Test out your game. Make sure that everything is in place. If you need the example file then you can find it in
the Examples folder saved as pac7.gmk.
Finishing Touches
Congratulations, your game is fully functional and pleasing to the eyes. The remainder of this tutorial is
completely optional but highly recommended for you to read. So, let's begin with the end, shall we?
In this final section, I will not be telling you exactly how to do things. I'll simply be telling you what would be
useful to add. You'll find that I've included a GMK that has all of the features that I'm going to mention in case
you want to use it to learn from. (The GMK is called pacfinal.gmk)
If you remember, in the original PacMan you could warp from one side of the level to the other. There's a
function in Game Maker called move_wrap(). You can find it in the help file or check the example to see it
work. Make sure to not allow the ghosts to exit the room. Wouldn't want them wandering around in oblivion.
Maybe adding a title screen and an actual ending screen would be nice. An ending screen is definitely more
rewarding than a popup box that says "Congratulations." Don't think it'll be easy to add these beginning and
ending screens. You'll have to edit the code that checks if you're in the last room to see if you won since there
will be an extra room at the end. Just look at the GMK for help.
See if you can make the transitions between the rooms cleaner. Look up how to in the Game Maker help file.
Want to go further? Try adding two speeds to PacMan. Maybe when you press space he'll go faster. A motion blur would
also be nice. These are not in the GMK. Trial and error is the way to go.
Congratulations
That's it! You've done it! You have successfully made a PacMan game from scratch. It has everything that a
game needs to succeed. Please, feel free to pass this tutorial on to others that may need it. I hope you've
enjoyed creating this game, I know I enjoyed creating this tutorial for you! Now, go on and try out your new
skills. Make some games!