Note: what appears here is what I prepared as a project for the "Computer Graphics I" course, which I attended at the University of Illinois at Chicago (course number EECS488) with Andrew Johnson as instructor.

Please click here and fill in the form before downloading (another window will appear).
[Click here to download the executable (Win32 exe + glut32.dll, zip archive)]
[Click here to download the source code (zip archive)]

Berzoik is a three-dimensional maze where you can freely move around, collect orbs and teleport yourself in another random point in the maze.

The objects are drawn in a wire-frame representation. The shapes of the objects and of the maze are configurable and can be modified by modifying the associated files.

The source code archive contains a Microsoft Visual C++ 6.0 projects and a berzoik.cpp file that can be compiled on every architecture (included Linux, Windows, SGI Irix, Sun Solaris, ...) provided that you have the GLUT libraries and headers installed.

Obviously the OpenGL libraries for your operating system are required too. To achieve the maximum performance I suggest you to go to the OpenGL website, click on download, and download and install the GLsetup program, which will install the best OpenGL driver for your graphic adapter.

Screen shots
The starting point.
A view while falling down after a teleportation.
A view depicting a teleport and some empty pedestals.

The official specifications of the assignment, as taken from the professor's website on October 2000. It should explain pretty well what the program does.

EECS 488: Assignment 3


Out: 10/17/00

Due: 11/7/00 at 3:00pm

In this third assignment you will get to play with 3D computer graphics by implementing a 3D version of theearly 80s game of Berzerk where you will create a perspective view window onto a maze that you walk through. (for those that have actually played 'berzerk', this game will become a bit more 'berzerk'-like in assignment 4 with the introduction of Otto.)

Your program will read in a datafile called maze.txt. This text file defines the shape of the maze and the objects inside it.

For example a very simple maze file could be:


The data file literally draws out the map of the maze. Each character in the text file represents a 5 foot long by 5 foot wide by 10 foot tall area. the character codes are defined in the table below. Each of the solid objects in the maze has a file defining the polygons that make up that object. The maximum size of the maze is 500 by 500 characters (that is 2500 feet by 2500 feet).

. Floor Space space.txt
# Wall wall.txt
D Doorway door.txt
X Starting Point start.txt
O Orb orb.txt
T Teleporter tele.txt
P Empty Pedestal ped.txt
(space) Empty space outside the walls -

Periods ('.') are empty areas inside the maze that the user can move through - so the only thing drawn here is a square on the floor showing the boundary of this space. Note that all of the things in the maze should have a floor beneath them. Walls are solid areas that the user can't move through. Doorways are areas the user can move through that have a slightly lowered ceiling, usually placed between 2 wall squares. This gives the user the effect of a doorway that can be used in both N/S and E/W configurations. An orb is a diamond shaped object on a low pedestal that the user can collect by walking over it. Once the orb is collected the space turns into an empty pedestal. A Teleporter is a low pyramidal shaped object that instantly teleports the user to some other random safe point in the maze (ie they are not trasported outside the maze, and they are not transported into a wall.) The starting point is marked in some appropriate way. Spaces in the data file (which may occur outside the walls of the maze if the maze is not rectangular in shape) are ignored. Note that this is a change from the original version of the assignment.

The format for each of the object files (e.g. wall.txt, door.txt. etc) is given below. Each object has its centerpoint defined as (0,0,0) at the center of the object at groundlevel. The coordinate system for these objects has X and Y forming the plane of the floor and Z being the height above the floor. In this case a wall segment is a block stretching from -2.5 to 2.5 in X and Y and stretching from 0 to 10 in Z.

For example, wall.txt could look like the left column in the following table:

6 number of polygons in the object (6)
1.0 0.0 0.0 RGB colour of the object (red)
4 number of vertices in the polygon (4)
-2.5 -2.5 0 vertex 1
2.5 -2.5 0 vertex 2
2.5 -2.5 10 vertex 3
-2.5 -2.5 10 vertex 4
4 number of vertices in the polygon (4)
2.5 -2.5 0 vertex 1
2.5 2.5 0 vertex 2
2.5 2.5 10 vertex 3
2.5 -2.5 10 vertex 4
4 number of vertices in the polygon (4)
2.5 2.5 0 vertex 1
2.5 2.5 10 vertex 2
-2.5 2.5 10 vertex 3
-2.5 2.5 0 vertex 4
4 number of vertices in the polygon (4)
-2.5 2.5 0 vertex 1
-2.5 2.5 10 vertex 2
-2.5 -2.5 10 vertex 3
-2.5- 2.5 0 vertex 4
4 number of vertices in the polygon (4)
2.5 -2.5 0 vertex 1
2.5 2.5 0 vertex 2
-2.5 2.5 0 vertex 3
-2.5 -2.5 0 vertex 4
4 number of vertices in the polygon (4)
2.5 -2.5 10 vertex 1
2.5 2.5 10 vertex 2
-2.5 2.5 10 vertex 3
-2.5 -2.5 10 vertex 4

You are responsible for creating the objects for the empty pedestal, the pedestal with orb, the starting point, and the teleporter. Their general shapes are given above. Within the data files you should set the following colours. The walls of the maze and the empty pedestal should be red. The teleporter should be light blue. The pedestal with the orb should be yellow. The starting point should be green.

The file names can be hard-coded in the program but this should be done in such a way that it would be easy and obvious how to change them.

As in assignment 2, you will be using lines on this assignment rather than filled polygons for all of the objects on the screen. For a large maze this means there could be many confusing lines on the screen. In assignment 4 we will use filled polygons and z-buffering to get around this problem, but for now on this assignment when you draw an object, you will progressively darken the colour of objects that are further away. That is, all objects within 10 feet of you are their given colour, all objects 110 feet away from you are coloured black, and inbetween you linearly darken the colour appropriatley. Later on we will see how fog can be used to do this automatically but here you will be doing it manually.

The user starts out facing North (towards the top of the datafile) at the position of the X. You move your viewpoint through the maze using the 'i' key to move forward, and can turn left and right using the 'j' and 'l' keys respectively. The user will always have their viewpoint at a constant height above the ground (5 feet above the ground.)You should not let the user move through any of the walls. For now you cannot move backwards, and you cannot strafe left and right - this makes the collision detection quite a bit simpler. You should turn and move through the maze at reasonable rates for a human being - that is you should move at somewhere between 1 and 5 feet per second forward, and you should turn at a rate of 30 to 90 degrees per second. If the user should attempt to move into a wall area, the user should slide along the wall instead. If the user tries to move through a corner their motion should stop.

The shell for this program is slightly different than that from the previous assignments. The major difference is that we are replacing the call to gluOrtho2D(LEFT_EDGE, RIGHT_EDGE, BOTTOM_EDGE, TOP_EDGE); with a call to gluPerspective(60, 1, 0.1, 110); which specifies the field of view in degrees, the aspect ratio, and the near and far clipping planes. On the first two assignments the camera did not move through the scene - it remained stationary though the scene was dynamically changing. On this assignment we will be keeping the scene relatively constant but moving the camera a lot. We will use gluLookAt() for this. gluPerspective gives the parameters of the camera defining its field of view; gluLookAt tells openGL where the camera is located and what direction it is pointed. It takes 9 floats as parameters. The first 3 are X, Y, Z of the camera's location. The second 3 are X, Y, Z of the point the camera is pointed at. The third 3 is a vector defining the 'up' direction. In the case of this program the first triple is where the user is located in the maze, the second triple should be computed to be a point directly in the line of sight of the user, and the third triple is 0, 0, 1 setting +Z to be up. So at the beginning of each loop through the display function you should call:


to set up the correct view before drawing the scene

You should set the user's movement speed and turning speed to some appropriate value for moving through the maze on the O2s. As with the first two assignments, the update rate of the data will be separate from the update rate of the graphics (which will remain at a maximum of 20 frames per second.)

Your program should be well commented and be a good example of literate programming.

As with assignments 1 and 2, your program will be submitted electronically and you need to be sure that it compiles and runs on the SGI O2s in the EECS lab.

As usual, I would suggest you get the program to work in sections. First I would deal with reading in a data file for a simple maze with just the walls and the user's starting position. Then deal with loading in the data file for a wall and drawing the walls of the maze on the screen. After that deal with moving through the maze and the collision detection routines. Finally add in the rest of the objects and add the code to deal with their specific properties.

Again, I would also highly recommend that you understand the code you are writing - you never know when you might need to reproduce it (hint hint).

I would also suggest that you take this opportunity to play with changing the parameters of the camera and seeing the affect those parameters have on the scene.