Making of a Pokemon game – Day 4

-Objective:

Model the states and basic displays such as the map and the user.

Design the screen and display the models accordingly.

-Files:

Graphics.hpp

- Initial State Diagram:

States:

1.     Dialogue à user has to follow the dialogue, which is textbased.

2.     Battle

3.     Fight

4.     Catch

5.     Run

6.     Attack

7.     Map à User walks around the map, which is read from the map.txt file

We will model the basic dialogue state, battle states, and map state.

 

Below is very basic state machine model for the system.

statemachine.png

 

-Screen design:

screen_design_01.png

 

screen_design_02.png

 

 

-Implementation: graphics.hpp:

Key implementations:

1. Defining color codes

//set colors

float color_red[3] = {1.0, 0.0, 0.0};

float color_floor[3] = {0.8, 0.8, 0.8};

float color_wall[3] = {0.9, 0.9, 0.9};

 

2. Drawing rectangle

void rect_2d(float xPos, float yPos, float zPos, float color[3])

{

    glEnable2D();

    glTranslatef(xPos, yPos, zPos);

    glBegin(GL_QUADS);

        glColor3f(color[0], color[1], color[2]);

        glVertex2d(0, 0);

        glVertex2d(30, 0);

        glVertex2d(30, 30);

        glVertex2d(0, 30);

    glEnd();

    glDisable2D();

}

 

void textbox_line(float xPos, float yPos, float zPos)

{

    glEnable2D();

    glTranslatef(xPos, yPos, zPos);

    glBegin(GL_QUADS);

        glColor3f(0.0, 0.0, 0.0);

        glVertex2d(0, 0);

        glVertex2d(screenWidth, 0);

        glVertex2d(screenWidth, screenHeight/3);

        glVertex2d(0, screenHeight/3);

 

        glColor3f(1.0, 1.0, 1.0);

        glVertex2d(10, 10);

        glVertex2d(screenWidth-10, 10);

        glVertex2d(screenWidth-10, screenHeight/3 -10);

        glVertex2d(10, screenHeight/3 -10);

 

    glEnd();

    glDisable2D();

}

Reading map

//draw the map

        ifstream map;

        map.open ("map.txt");

        string oneLine;

        int i = 0;

        int j = 0;

        while (!map.eof())

        {

            getline(map,oneLine);

            for(string::iterator it = oneLine.begin() ; it < oneLine.end(); it++ )

            {

                if( *it == '1')

                {

                    rect_2d((float)(i*30),(j*30),0,color_floor);

                }

                else

                {

                    rect_2d((float)(i*30),(j*30),0,color_wall);

                }

                i++;

            }

            j++;

            i = 0;

            //draw the Player

            rect_2d(playerPos[0],playerPos[1],playerPos[2],color_red);

        }

Render Scene Modification

if(userMode == "MAP")

    {

        //draw the map

        ifstream map;

        map.open ("map.txt");

        string oneLine;

        int i = 0;

        int j = 0;

        while (!map.eof())

        {

            getline(map,oneLine);

            for(string::iterator it = oneLine.begin() ; it < oneLine.end(); it++ )

            {

                if( *it == '1')

                {

                    rect_2d((float)(i*30),(j*30),0,color_floor);

                }

                else

                {

                    rect_2d((float)(i*30),(j*30),0,color_wall);

                }

                i++;

            }

            j++;

            i = 0;

            //draw the Player

            rect_2d(playerPos[0],playerPos[1],playerPos[2],color_red);

        }

        //cout<<"map_dimension:" << i << ","<< j<<endl;

 

    }

    else{

    textbox_line(0,0,0);

    drawString(dialogueStr,50,50);

    }

 

 

Entire source file:

//set colors

float color_red[3] = {1.0, 0.0, 0.0};

float color_floor[3] = {0.8, 0.8, 0.8};

float color_wall[3] = {0.9, 0.9, 0.9};

 

void glEnable2D()

{

    int vPort[4];

    glGetIntegerv(GL_VIEWPORT, vPort); // Get a copy of the viewport

 

    // Save a copy of the projection matrix so that we can restore it

    // when it's time to do 3D rendering again.

    glMatrixMode(GL_PROJECTION);

    glPushMatrix();

    glLoadIdentity();

    glOrtho(0, vPort[2], vPort[3], 0, -1, 1); // Set up the orthographic projection

 

    glMatrixMode(GL_MODELVIEW);

    glPushMatrix();

    glLoadIdentity();

 

    // Make sure depth testing and lighting are disabled for 2D rendering until

    // we are finished rendering in 2D

    glPushAttrib(GL_DEPTH_BUFFER_BIT|GL_LIGHTING_BIT);

    glDisable(GL_DEPTH_TEST);

    glDisable(GL_LIGHTING);

}

 

void glDisable2D()

{

    glPopAttrib();

    glMatrixMode(GL_MODELVIEW);

    glPopMatrix();

    glMatrixMode(GL_PROJECTION);

    glPopMatrix();

}

 

void drawString(string msg,int x, int y) {

    glEnable2D();

 

    // Draw text on screen at (x,y) where top-left is (0,0)

    // in an 18-point Helvetica font

    // TODO: dynamically load text here and center it

    glColor3f(0.0, 0.0, 0.0);

    glRasterPos2f(x, y);//x,y

    glutBitmapString(GLUT_BITMAP_HELVETICA_18, (const GLubyte*)msg.c_str());

 

    glDisable2D();

}

 

 

void process_key(unsigned char key, int x, int y)

{

    switch(key)

    {

        case '1':

            if (userMode == "BATTLE")

            {

                Fight(hero,pMonster);

            }

            else if (userMode == "FIGHT")

            {

                Attack(hero,pMonster);

            }

            break;

        case '2':

            if (userMode == "BATTLE")

            {

                Catch(hero,pMonster);

            }

            break;

        case '3':

            if (userMode == "BATTLE")

            {

                Run();

            }

            break;

        case 13:

            if (userMode == "DIALOGUE")

            {

                cout << "enter"<< endl;

                string output = dialogueQueue[dialogueLineNumber];

                if (output == "<USERNAME>")

                {

                    updateDialogue("What is your name young pokemon trainer? ");

                    //cin >> userName;

                    updateDialogue("So your name is  _________ ?");

                }

                else if (output == "<HERO_INIT>")

                {

                    hero -> SetName("Ash Ketchum");

                    updateDialogue(hero -> GetName() + "");

                }

                else if (output == "<BATTLE>")

                {

                    pMonster = new Pikachu();

                    battleMenu(hero,pMonster);

                }

                else if (output == "<TRAINER_INIT>")

                {

                    Monster* pMonster1 = createRandomMonster();

                    Monster* pMonster2 = createRandomMonster();

                    Monster* pMonster3 = createRandomMonster();

                    Trainer* pTrainer = new Trainer;

                    pTrainer -> addMonster(pMonster1);

                    pTrainer -> addMonster(pMonster2);

                    pTrainer -> addMonster(pMonster3);

                    pTrainer -> GetTrainerInfo();

                    pTrainer -> itsTalk();

                    for (int i = 0; i < pTrainer -> GetMonsterCount(); i++)

                    {

                        pMonster = pTrainer -> GetMonster(i);

                        battleMenu(hero,pMonster);

                    }

                }

                else if (output == "<MAP_INIT>")

                {

                    userMode = "MAP";

                }

                else

                {

                    updateDialogue(dialogueQueue[dialogueLineNumber]);

                }

                dialogueLineNumber ++;

            }

            break;

    }

    glutPostRedisplay();

}

 

void process_special_key(int key, int x, int y)

{

    switch (key) {

    case GLUT_KEY_RIGHT:

    if(playerPos[0] <=1260&&userMode == "MAP")

    {

        playerPos[0]=playerPos[0]+10;

        //updateDialogue("RIGHT");

    }

    // move right

    break;

    case GLUT_KEY_LEFT:

    if(playerPos[0] >=10&&userMode == "MAP")

    {

        playerPos[0]=playerPos[0]-10;

        //updateDialogue("LEFT");

    }

    // move left

    break;

    case GLUT_KEY_UP:

    if(playerPos[1] >=0&&userMode == "MAP")

    {

        playerPos[1]=playerPos[1]-10;

        //updateDialogue("UP");

    }

    // move up

    break;

    case GLUT_KEY_DOWN:

    if(playerPos[1] <=780&&userMode == "MAP")

    {

        playerPos[1]=playerPos[1]+10;

        //updateDialogue("DOWN");

    }

    // move down

    break;

    case GLUT_KEY_F2:

    // TODO: set each Fn key to diff configurations of shapes/positions

    break;

    case GLUT_KEY_F12:

    break;

    default: break;

    }

    glutPostRedisplay();

}

 

void process_mouse(int button, int state, int x, int y)

{

    switch (button) {

    case GLUT_LEFT_BUTTON:

    break;

    default: break;

    }

}

 

void rect_2d(float xPos, float yPos, float zPos, float color[3])

{

    glEnable2D();

    glTranslatef(xPos, yPos, zPos);

    glBegin(GL_QUADS);

        glColor3f(color[0], color[1], color[2]);

        glVertex2d(0, 0);

        glVertex2d(30, 0);

        glVertex2d(30, 30);

        glVertex2d(0, 30);

    glEnd();

    glDisable2D();

}

 

void textbox_line(float xPos, float yPos, float zPos)

{

    glEnable2D();

    glTranslatef(xPos, yPos, zPos);

    glBegin(GL_QUADS);

        glColor3f(0.0, 0.0, 0.0);

        glVertex2d(0, 0);

        glVertex2d(screenWidth, 0);

        glVertex2d(screenWidth, screenHeight/3);

        glVertex2d(0, screenHeight/3);

 

        glColor3f(1.0, 1.0, 1.0);

        glVertex2d(10, 10);

        glVertex2d(screenWidth-10, 10);

        glVertex2d(screenWidth-10, screenHeight/3 -10);

        glVertex2d(10, screenHeight/3 -10);

 

    glEnd();

    glDisable2D();

}

 

 

void render_scene() {

    glMatrixMode(GL_MODELVIEW);

    // clear all pixels to clear colour

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //-----------------------my edit starts here ---------------------------------//

 

    if(userMode == "MAP")

    {

        //draw the map

        ifstream map;

        map.open ("map.txt");

        string oneLine;

        int i = 0;

        int j = 0;

        while (!map.eof())

        {

            getline(map,oneLine);

            for(string::iterator it = oneLine.begin() ; it < oneLine.end(); it++ )

            {

                if( *it == '1')

                {

                    rect_2d((float)(i*30),(j*30),0,color_floor);

                }

                else

                {

                    rect_2d((float)(i*30),(j*30),0,color_wall);

                }

                i++;

            }

            j++;

            i = 0;

            //draw the Player

            rect_2d(playerPos[0],playerPos[1],playerPos[2],color_red);

        }

        //cout<<"map_dimension:" << i << ","<< j<<endl;

 

    }

    else{

    textbox_line(0,0,0);

    drawString(dialogueStr,50,50);

    }

 

    //---------------------------------------------------------------------------//

    glFlush(); // draw graphics in buffer immediately

    glutSwapBuffers(); // switch buffers for double buffering

}

 

void resize_scene(int w, int h)

{

    if (h == 0)

    h = 1; // DON'T divide by zero - please?

    GLfloat ratio = 1.0 * w / h;

    glViewport(0,0,w,h); // set the viewport to be the entire window

 

    // reset the coordinate system

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

 

    // set the correct perspective

    gluPerspective(45,ratio,1,1000);

    //GLdouble top = tan(0.5*PI/4.0)*1.0; // top = tan(fov*0.5)*near

    //glFrustum(ratio*(-top),ratio*top,-top,top,1.0,1000.0);

 

    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();

    // perspective transformation

    // LookAt(eyeX,eyeY,eyeZ, eye point

    // centerX,centerY,centerZ, reference point

    // upX,upY,upZ) "up" vector direction

    gluLookAt(0,0,20,

    0,0,1,

    0,-1,0);

 

 

    glutPostRedisplay();

}

 

void idle_event() {

 

}

 

void init() {

    glClearColor(1.0,1.0,1.0,0.0);

    //glShadeModel(GL_FLAT);

    glEnable(GL_DEPTH_TEST);

    glDisable(GL_CULL_FACE);

    glEnable(GL_TEXTURE_2D);

 

    // set up perspective

    glPushAttrib(GL_MATRIX_MODE);

    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    // LookAt(eyeX,eyeY,eyeZ, eye point(camera)

    // centerX,centerY,centerZ, reference point (where to look)

    // upX,upY,upZ) "up" vector direction

    gluLookAt(0,0,0,

    0,0,1,

    0,1,0);

    glPopAttrib();

}

 

void initialize_screen(int argc, char* argv[]) {

    // initialize (free)GLUT/OpenGL

    glutInit(&argc, argv);

 

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);

    GLint init_win_size_x = screenWidth, init_win_size_y = screenHeight;

    glutInitWindowSize(init_win_size_x, init_win_size_y);

    GLint init_win_pos_x = 0;

    GLint init_win_pos_y = 0;

    cout << "Screen Size: " << glutGet(GLUT_SCREEN_WIDTH) << " " << glutGet(GLUT_SCREEN_HEIGHT) << endl;

    cout << "Window Size: " << init_win_size_x << " " << init_win_size_y << endl;

    cout << "Window Coords: " << init_win_pos_x << " " << init_win_pos_y << endl;

    glutInitWindowPosition(init_win_pos_x, init_win_pos_y);

    GLint window_id = glutCreateWindow("Pokemon");

    init();

 

    // register callbacks

    glutDisplayFunc(render_scene);

    glutReshapeFunc(resize_scene);

    glutKeyboardFunc(process_key);

    glutSpecialFunc(process_special_key);

    glutMouseFunc(process_mouse);

    glutIdleFunc(idle_event);

 

    glutMainLoop();

    glutDestroyWindow(window_id);

 

}

 

Result:

During Dialogue:

screenshot1.png

During Map state:

screenshot2.png