CMPS-4490 Game Design Lab-1


Step 1:
Start by creating your semester directory structure on Odin.

Run the following script...


Step 2:
Do your work in your /4490/1 folder.

Start with the framework at:

Name your program /4490/1/game1.cpp on Odin.

Follow along with Gordon to modify the program.

Google search topic: linux console kbhit cboard

1. Bring in the kbhit function from the sample code.
   Look for post by itsme86.

   This function lets you receive keyboard input without pressing Enter.
   Just right for an action game.

2. Build the game functionality...

   Your game will ask the user to press a key, and continue pressing
   a key over and over.

   Your program will display the average time-span between key presses,
   in seconds.

   The player's goal is to get a display of exactly 1.0 seconds, and
   accomplish it in the fewest number of key-presses.

   The difficulty increases as the goal is set closer to exactly 1.0 seconds.

   Define a tolerance such as 0.05 or 0.001

   You may input a tolerance from the command-line.

3. Show an introduction screen.

4. Show the game in-progress.

5. Show a game-over screen with score.

Step 3:
When we finish the console program, we will begin working with
a 3D graphics framework. We will review the program together,
then you will have a few specific tasks to complete as homework.

Please get a copy of the directory containing the second part of lab-1.


Copy the files to your own 4490/1/fps/ Odin folder please.

It will produce the following scene.

Your job is to give a user the ability to move the camera
in a first-person perspective. Move the camera through the tube.

Current keyboard controls:
  movement      key
  ------------  ---------
  move up       up arrow
  move down     down arrow
  move left     left arrow
  move right    right arrow
  move forward  f
  move back     b

You may change the controls and even incorporate mouse control.

Your goal is the following camera control...

  1. Look to the left or right
  2. Look up or down
  3. Move up or down
  4. Move in the direction the camera is looking (forward or back)
  5. Move left/right in relation to where the camera is looking

We will discuss this in class and do some of the work together
on the big-screen.

You can create a camera class such as

class Camera {
    Vec position;
    Vec direction;
    Camera() {
        VecMake(0, 1, 8, position);
        VecMake(0, 0, -1, direction);
    void translate(float x, float y, float z) {
        position[0] += x;
        position[1] += y;
        position[2] += z;
    void lookLeftRight(float angle) {
        Matrix mat;
        Vec rot = {0.0, angle, 0.0};
        yy_transform(rot, mat);
        trans_vector(mat, direction, direction);
    void lookUpDown(float angle) {
        Matrix mat;
        Vec rot = {angle, 0.0, 0.0};
        yy_transform(rot, mat);
        trans_vector(mat, direction, direction);
    void moveLeftRight(float dist) {
        //get perpendicular vector to direction/up
        Vec left;
        VecCross(direction, up, left); 
        position[0] += left[0] * dist;
        position[1] += left[1] * dist;
        position[2] += left[2] * dist;
    void moveUpDown(float dist) {
        //just move straight up or down
        position[1] += dist;

Try to get freedom of movement similar to this...

Code needed:
To accomplish the look-up and look-down (pitch) camera control, you will need
the following code segment.

The following function builds a rotation matrix, but it will rotate on any
axis given, not just x,y,z axis. Indicate an axis using a vector.

   X axis is { 1, 0, 0 }
   Y axis is { 0, 1, 0 }
   Z axis is { 0, 0, 1 }

Then use the matrix created to transform the camera direction using trans_vector.

This function was used in the animation to tilt the camera downward.

void matrixFromAxisAngle(const Vec v, Flt ang, Matrix m)
    // arguments
    // v   = vector indicating the axis
    // ang = amount of rotation
    // m   = matrix to be updated
    // This source was used during research...
    struct Axisangle {
        Flt angle;
        Flt x,y,z;
    } a1;
    a1.x = v[0];
    a1.y = v[1];
    a1.z = v[2];
    a1.angle = ang;
    Flt c = cos(a1.angle);
    Flt s = sin(a1.angle);
    Flt t = 1.0 - c;
    m[0][0] = c + a1.x * a1.x * t;
    m[1][1] = c + a1.y * a1.y * t;
    m[2][2] = c + a1.z * a1.z * t;
    Flt tmp1 = a1.x * a1.y * t;
    Flt tmp2 = a1.z * s;
    m[1][0] = tmp1 + tmp2;
    m[0][1] = tmp1 - tmp2;
    tmp1 = a1.x * a1.z * t;
    tmp2 = a1.y * s;
    m[2][0] = tmp1 - tmp2;
    m[0][2] = tmp1 + tmp2;
    tmp1 = a1.y * a1.z * t;
    tmp2 = a1.x * s;
    m[2][1] = tmp1 + tmp2;
    m[1][2] = tmp1 - tmp2;

void screenShot()
    //A capture of the OpenGL window client area.
    static int inc = 0;
    //Get pixels...
    unsigned char *data = new unsigned char [g.xres * g.yres * 3];
    glReadPixels(0, 0, g.xres, g.yres, GL_RGB, GL_UNSIGNED_BYTE, data);
    //Write a PPM file...
    char ts[256], tj[256];
    sprintf(ts, "./images/img%03i.ppm", inc);
    sprintf(tj, "./images/img%03i.jpg", inc);
    FILE *fpo = fopen(ts, "w");
    fprintf(fpo, "P6\n");
    fprintf(fpo, "%i %i\n", g.xres, g.yres);
    fprintf(fpo, "255\n");
    //Image is upside-down.
    //Go backwards a row at a time...
    unsigned char *p = data;
    p = p + ((g.yres-1) * g.xres * 3);
    unsigned char *start = p;
    for (int i=0; i<g.yres; i++) {
        for (int j=0; j<g.xres*3; j++) {
            fprintf(fpo, "%c", *p);
        start = start - (g.xres*3);
        p = start;
    delete [] data;
    char t2[256];
    sprintf(t2, "convert %s %s", ts, tj);

What to turn in...
Gordon will find your work out on Odin.