Our program is a 3D tribute to Pacman, probably the world most
famous Video Game. In short : eat the pellets, avoid the
ghosts or use the red Super-Pellets to eat them... If you
eat all the pellets, then you go to the next level. You
can choose between the camera position, from the classic
2D view to a fully immersive "you are Pacman"
standpoint...

If you play in COOL mode, then you will have the
ability to jump, be invisible, and shoot the ghosts with
a freezing gun... but if you want to remember the old
days, you can play in OLD SCHOOL mode !

The levels are simply described in ASCII format in the
Levels directory, making it
very simple to modify them or create new ones. We have
implemented 4 different levels. If you ever finish them,
then you come back to the first one but the ghosts will
be much more aggressive...

You can access the game menu at any time by pressing
the ESC key. From there, you can :

Start a New Game

View the Introduction sequence

View the Highscores

Change the game options

Quit the game

1. Basic
Controls

Move Pacman with the arrow keys

F2 sets the Classic
view

F3 sets the 3D View

F4 sets the Doom View

In Doom View use
ALT-LEFT and ALT-RIGHT to do a lateral move

2. Special
Controls

If you are in COOL gameplay mode :

Use Z to shoot a ghost with a freezing bullet.
You can have additionnal ammunitions with a Blue
torus pellet.

The Green torus pellet makes you invisible for a
while...

Use the SPACE BAR to jump

3. Options

You can navigate through the options in the Game Menu
using the arrow keys, ENTER to change a value, and ESC to
return to the game. Some options also have a shortcut,
indicated as [F] for the F key:

Game view [F2 F3 F4] : Classic | 3D View | Doom
View

Game play : Old school | Cool

Difficulty : Easy | Normal | Hard

Level of Detail [L] : Low | High

Reflection [R] : On | Off

Draw floor [D] : On | Off

Fog [F] : On | Off

Shading [S] : On | Off

Set Defaults

C. Extra Features

On-screen control panel : We
have used two methods to display informations on
screen. The Score, Remaining lives,
and Ammunition items are drawn as 3D
objects in the scene, and can be viewed in the
CLASSIC view (orthogonal projection). The Highscores
panel is also an orthogonal projection of 3D
objects. For the Game Menu we have used font.c code from the
redbook, with some minor modifications, e.g.
changed some bitmaps in order to represent
"2" and "3"... We pause the
game, set glutIdleFunc(NULL),
copy the entire screen, 800x600, multiply each
pixels r, g, and b values by 0.5 in order to
darken the background scenery, and then wrote the
menu text to the foreground using screen
coordinates...

View frustum culling : We can
take advantage of the maze construction method
for our view frustum algorithm : all the objects
are drawn within a maze unit cell, so we can use
a same cubic bounding box for all the objects in
the scene. Actually, we can come with a more
straightforward algorithm : given the camera
parameters, we just have to compute a binary mask
over the maze, and the value of one cell tells us
if the object is to be drawn. This is how we
implemented view frustum culling. The binary mask
is computed using viewing angle calculations.
This feature is really boosting the game in Doom
View, where 75% of the scene is out of the
camera frustum.

Level of detail control : We
want to compute a parameter 0 < alpha <
1 which will correspond to the object level
of detail. We first compute the distance d
from the object to the camera. alpha is
then computed as a non-linear function of d
( alpha = cos(k * d) ), leading to a
less perceptible loss of quality. Since all the
objects are drawn within a maze unit cell, it
makes sense to have only one parameter per
object. Within each object drawing function, we
specify the precision range, for example instead
of callingglutSolidSphere (.25, 10,
10), we will callglutSolidSphere(.25,
getResolution(3, 10), getResolution(3,10))
If level of detail is enabled, the getResolution function will
interpolate between the min and max
values using the value of alpha, else it
will return the max value. This feature
is greatly improving performance in the 3D Views
without fog, when the whole maze is to be
displayed.

Reflection - Multipass rendering
: In order to get reflection to work we used the dinoreflection example as a
base (the code was obtained from the opengl
examples website). Basically, we took our scene,
flipped it upside down into the negative 1 plane
on the z-axis, and used a blend function on our
floor in order to see through it. We also used
the stencil buffer so that when reflecting our
surface, if the user happens to look underneath
the floor, s/he won't see the "fake"
upside scene which creates the reflection. So, we
draw our floor first using the stencil buffer, so
that when drawing our reflected scene, the pixels
which get drawn are the pixels that are turned on
in the stencil buffer (or the pixels which are at
the same location as part of the floor). If the
reflected scene wants to draw a pixel in a spot
where the stencil buffer is not turned on, then
we don't draw that part of the scene...

Sound : The game includes intro
music and sound effects wich rely on the PlaySound() function. We
have found Pacman's original sound effects on the
web [see sources], and we synchronize sounds with
the game events. We also use sound timing for the
intro sequence : the titles appearing on the
screen are synchronised with the music, using
real time management functions.

Screenshot from the original Pacman

AI : We wanted to integrate in
our game the original AI behavior of the ghosts
(those that were in the original Pacman game).
Without AI, the game was not interesting to play,
since a random behavior is too simple to play.
Each ghost has its own personality:
Shadow is the red ghost and it
chases Pacman all the time, using a straight
forward tracking algorithm. Speedy
is the pink ghost. It is very fast but moves in a
random manner. Bashful
is the blue ghost: it is shy at the beginning and
escapes from pacman all the time, but if Pacman
approaches him to much, then it is not shy
anymore and begins to chase him (Pacman is then
chased by two ghosts at the same time...). Pokey
is the orange ghost and is slow and moves in a
random manner. When Pacman eats a special pellet
that allows him to eat the ghost, all the ghosts
become blue, move twice as slow as before and
change their direction. After that try to escape
Pacman, still going twice as slow as before. When
Pacman eats a ghost, the eyes of the ghost come
back home...

Fire - Procedural Modeling : We
assigned "hot" values to random indices
in the bottom row of an array, once these values
were assigned, we moved up the array, and for
each pixel, assigned an average of surrounding
pixels...