Master QDCS, UE: Object Oriented Programming
First Semester 2023-2024
Project : Patrick Amar



Object Programming Project



Working in pairs:

For this project you will work with another person. Of course, you have to work together: design the program together, type it in and edit it together on the computer. There is no way that some of you will do the work, and others will add their names to it! You will only have to hand in one set of reports with your names on them.

How to report:

You will have to give me a report and a program: that is to say several files that you will group together in a ZIP or RAR or TGZ archive; You will have to send it to me by mail at the following address: pa@lri.fr. Please send only one mail per pair.

The goals of this project:

  • You will learn how to write a program from informal specifications (statement in English).
  • Familiarize yourself with the fact that your programs will be reused by others later on; therefore, write them legibly and comment them judiciously.
  • Train you to encapsulate your data and methods to get robust programs.
  • Show you the interest of separating the processing part of a program from its user interface part.
  • What will be provided to you

    You will be provided with various C++ classes and functions allowing the 3D display with OpenGL of the maze and the various textures.

    What do you have to do in this project?

    We propose to make a simple Kill them all type game, with a 3D display, also simplified.

    The machine animates guard-like characters whose goal is to protect a treasure hidden in a room of the labyrinth, which you, the hunter, try to take.

    The hunter moves in the maze in a direction that is indicated by the mouse and/or the keyboard, the human player has complete control over the hunter. On the other hand, the guards are incarnations of the machine: they are animated by a kind of artificial instinct which pushes them to attack the hunter.

    Each character has an initial survival capital that is decremented each time he/she suffers an attack from one of his/her opponents. This capital is incremented when the character goes a certain amount of time without suffering a wound (or any other criteria such as finding health reserves in the form of survival boxes). The initial capital of each type of character (guards, hunters) and the recovery time should be parameters of the program.

    The guards have two operating states:

    The criteria that decide the state of a guard is simple: a guard that sees the hunter switches to attack mode, otherwise it goes into patrol mode. A guard sees the hunter when there is no obstacle between the guard and the hunter.

    Conversely, the hunter can attack the guards, he shares with the guards the characteristic of having a variable accuracy of shooting with his state of health. The coefficient is not the same as for a guard because the hunter's shot is directed by a human (and is therefore much less accurate than what the machine can do).

    The labyrinth

    The constructor of the Labyrinth class will be used to initialize a labyrinth according to the internal representation of the game program from a textual representation of the labyrinth (using the + - | characters).

    Conceptually the labyrinth is in 2D, it is the graphic display that will make it 3D, your characters move in a plane where the walls of the rooms (or corridors which are only particular rooms) are straight horizontal or vertical lines. The labyrinth is closed, and has two particular rooms:

    To furnish the labyrinth, you can place boxes that prevent the passage. Posters (gif or jpg images) can also be displayed on the walls.
    The (initial) positions of the hunter, the guards, the treasure and the boxes in the labyrinth can be identified using specific letters:

    A poster will be identified by the (lower case) letter representing it, which will be put in place of the '-' or '|' corresponding to a wall section (see the example file).

    Structure of the program

    To make your code readable, you will put a big comment at the beginning of each file indicating what the classes in it are for, how they fit together to make up the module and what the module is for. You will also put a small comment at the beginning of each method indicating what it does, the meaning of each of its arguments, and the return value. Finally, put a small comment indicating what each data field in your classes represents. Be sure to respect the naming conventions that were indicated in the course.

    It is up to you to design the architecture of your program so that it has all the qualities required of a good program: simplicity, conciseness, clarity, etc.

    Among other things, start by identifying the objects involved in the program, indicate how these objects relate to each other to do what you are asked to do. At the same time, start listing the characteristics of these objects: attributes and methods, to identify their class. Then, look at the relationships between these classes, perhaps they share characteristics? You can implement these relationships with derivation or use.

    Classes from which your own should be derived

    In order to take advantage of the 3D display with OpenGL, your classes corresponding to the maze and the guards/hunters will have to derive from the following downloadable models:

  • the Environment class which also defines structures for walls, boxes and possibly posters.
  • the Mover class which defines the minimal features of the guards/hunters that will be used by the GUI.
  • The labh-proto-fltk.tgz archive which contains all the header files (Hunter.h Environment.h Keeper.h Mover.h FireBall.h) and the example files (Labyrinth.h Labyrinth.cpp Makefile). This is the object file to link with your code to obtain an executable. The main function is contained in this file so don't define it yourself!
    This archive also contains all the textures (.jpg files) and the guard model (guard.md2).
  • Of course, you must not modify the content of these header files by even one character...
    Except for Labyrinth.h and Labyrinth.cc, which you must rewrite: your Labyrinth class (derived from Environment) must have a constructor which takes a char* argument which is the name of the file defining the maze.

    The Environment::scale constant is a scale factor to convert floating point coordinates of characters into integer coordinates in the map. This conversion is done as follows: (for example)

                 Mover*	m;
    
                 int i = (int) (m -> _x / Environnement::scale);
                 int j = (int) (m -> _y / Environnement::scale);
    

    Nothing like an example to understand how to use code you didn't write yourself. Download the LabyrintheProto.tgz archive (see above):

  • Labyrinth.h and Labyrinth.cpp which define a trivial maze.
  • Chasseur et Gardien which are two almost empty examples of derived classes of the Mover class
  • Makefile which shows you the libraries to use for linking your application.
  • The Mover class (and consequently its Gardien and Chasseur derived classes) allows the display of a projectile (fireball) which requires the inclusion of the FireBall.h file and a virtual method:

    bool process_fireball (float dx, float dy)

    where an example of which is given in Chasseur.h. This function is called automatically when a shot is initialized (see the fire method of the Chasseur class). It returns true if the move is accepted and false if there is a collision. In case of collision, the ball will automatically explode.