Friday, 19 June 2015

Pacman .... how it works

This picture is actually from Construct 2, I thought it might help with the explanatory bits.


This is concerned with basic construction. As you can see only half the maze is there, and it's a bit scruffy.

Events 1,2 and 3 just mirror the horizontal and vertical bars on the other side, as Pacman's maze is symmetrical.

Events 4-7 tidy it up - make things a fixed width and an exact height - in terms of "maze units" - this is MAZE_BOX_SIZE , the width of the maze grid, and position it in the right place. Doing it this way makes it easy to change the width of the maze pieces.

Events 8-13 create the power pills (event 9) and the dots. We scan each square and put a pill there if there isn't a power pill there, and it doesn't overlap a not-dot space (the red crosses). They are all then moved to the bottom of their layer.

Events 14-19 reset the ghosts, this is repetitive except for the animation (held in an instance variable)  and the "brains" - which is the chance of it chasing the player rather than just wandering aimlessly.

Finally, events 20-22 reposition the Pacman character and clear the two dots either side of it.

Moving Objects

The Pacman maze can be thought of as a bit like a monorail, with the rails passing through the middle of each square. A specialist moving routine is designed to keep them on the rails - so it can't move up when it is half way between squares for example. This applies to all objects in the Moveables family.

What happens is as follows. It first works out whether the moveable can move horizontally or vertically by seeing how close it is to the 'rail' (Events 5,6) - there is an adjustment so it can be close without being on top of it. It then calls the function named in the instance variable controlFunction to decide what to do (7) - which is different for Pacman (keyboard control) and Ghosts (AI ... ish).

Events 8 and 9 filter those move options according to whether it is possible or not, and then 10 and 11 update the actual direction if there is a change - so moveables will keep moving in one direction until you tell them a different one.

If it is moving, then 13 and 14 lock it to the rail in either direction, and a collision check is done in 15 - and if it can't move it cancels the moving direction (dx,dy) and puts it back in the middle of the rail. Event 16 is the same but is the special case of going down through the door to the Ghosts's den (hence the dy > 0 condition) which you cannot do, but moveables can go up through the door.

Finally, 17 actually physically moves it, and 18 and 19 deal with the tunnel at either end. Lastly another function is called to animate it appropriately.

Event 23 is the Pacman controller which sets the required dx and dy depending on the keyboard position. Event 29 controls a ghost - at any 'junction' (where a horizontal and vertical rail meet) there's a one in four chance of picking a new direction (forced by setting dx = dy = 0). 33 and 34 track whether the last one was a junction, so it can detect moving into a junction. If a directional change is desired (35), 36-39 set a horizontal or vertical direction, chasing (or running away from) the player dependent on the ghost's intellligence. Finally, if it is on a red cross it is forced to move up (i.e. it's in the middle)

Events 41-47 handle animation - the animations are different colours, and there are 4 pairs of frames in each colour. This maps that depending on elapsed time. Effectively I have written my own animation and moving code.

Event 46 is left in from testing, if you press X all the ghosts go home ... shouldn't be there.

Event 49 onwards makes a specific ghost go home - its isControlled instance variable is set to false, and a target is picked and stored in dx,dy. A pathfinder behaviour is used to find away back to the start, displaying eyes. When it reaches home it resets and goes back to being controlled by the AI rather than pathfinding.


The controller is an object which glues everything together. Doing it this way was a bit experimental.

Event 1 creates it if it doesn't exist (it's created on the Title screen), Event 2 resets in case of a new game, Event 3 calls the code to restart the level, and event 4 actually starts it going once the intro tune has been played.

Event 5 scores a dot, and Event 6 a powerpill. This also plays the new sound, and starts a timer which fires when the chasing ends. Finally 7 sets the attract direction to 'run away' (-1) and the animation code in the previous event file handles the blue and white look.

When the power pill times out, or all the ghosts have been eaten, all ghosts are reset to chasing mode.

Event 10 onwards handles collision with ghosts. It only happens when the ghost is controlled by AI (e.g. it's not returning to the middle). If the ghost is being chased, that is scored, and if not, we are in death mode, so everything is stopped and the death animation and sound is played ; when that ends we lose a life (14) and if we have lives left reset everything, but not the powerpills and dots. If it's the end - end (16) we go to the title screen.

Event 17 hands the completion stuff - no dots or power pills. We flash the maze (18,19,20) and when complete we either go the intermission (I only did one) or the next level.

Event 22 onwards handles the creation of fruit, and 23 makes it go away. If it's been eaten (24) it will be invisible, so if not,we make it disappear and go back to the first fruit. If it is eaten we go to the next fruit in the list, each one giving more points (25)

Event 26 is a function that starts a new level. On level 1 (only) it plays the little tune, skipping it if not (28)

Event 29-32 are simple functions that updte the score and lives. The only interesting one is 30, which does the extra life at 10000 points.

Of the others, IntermissionObjects just plays the little cartoon after Level 2. Title event is broadly the same as the rest. It uses blanker objects - black tiled backgrounds - with a time out to make things appear in the classical fashion.

So I'm off for a week now, when I return I'll continue with the next game, Berzerk.

No comments:

Post a Comment