/* cfield2_Assignment3.c */ /* The program that impliments a specific instance of a game that looks similar to pacman. This is done to demonstrate the basic functions of OpenGL programs. */ /* Christopher Field */ #include #include #include #include #include GLfloat red[3] = {1.0, 0.0, 0.0}; GLfloat green[3] = {0.0, 1.0, 0.0}; GLfloat blue[3] = {0.0, 0.0, 1.0}; GLfloat black[3] = {0.0, 0.0, 0.0}; GLfloat white[3] = {1.0, 1.0, 1.0}; GLfloat gray[3] = {0.5, 0.5, 0.5}; GLfloat yellow[3] = {1.0, 1.0, 0.0}; GLfloat magenta[3] = {1.0, 0.0, 1.0}; GLfloat cyan[3] = {0.0, 1.0, 1.0}; GLint fillmode = 0; /* In the following grid, 0 is empty, 1 is a wall, 2 is food, and 3 is the location of the player */ int player_x = 5, player_y = 14; int levelOne_width = 20, levelOne_height = 20; int levelOne[20][20] = {{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,2,2,2,2,2,1,1,2,2,2,2,2,1,1,1,1}, {1,1,1,2,2,2,2,2,2,1,1,2,2,2,2,2,2,1,1,1}, {1,1,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,1,1}, {1,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,1}, {1,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,1}, {1,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,1}, {1,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,1}, {1,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,1}, {1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1}, {1,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,1}, {1,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,1}, {1,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,1}, {1,2,2,2,2,3,2,2,2,1,1,2,2,2,2,2,2,2,2,1}, {1,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,1}, {1,1,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,1,1}, {1,1,1,2,2,2,2,2,2,1,1,2,2,2,2,2,2,1,1,1}, {1,1,1,1,2,2,2,2,2,1,1,2,2,2,2,2,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}}; /* forward declarations of functions */ void display(void); void keypress(unsigned char key, int x, int y); void main_menu(int value); void draw_wall(float i, float j); void draw_food(float i, float j); void draw_player(float i, float j); int main(int argc, char** argv) { /* open a window */ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500, 500); glutInitWindowPosition(100, 100); glutCreateWindow(argv[0]); /* OpenGL init */ glClearColor(0, 0, 0, 0); /* set background color black */ /* callback functions */ glutDisplayFunc(display); glutKeyboardFunc(keypress); glutCreateMenu(main_menu); glutAddMenuEntry("Fill/Outline", 1); glutAddMenuEntry("Quit", 2); glutAttachMenu(GLUT_LEFT_BUTTON); /* event handler */ glutMainLoop(); return 0; } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); int i, j, currentGridValue; for(i = 0; i < levelOne_height; i++) { for(j = 0; j < levelOne_width; j++) { currentGridValue = levelOne[i][j]; switch(currentGridValue) { case 0: break; case 1: draw_wall(i, j); break; case 2: draw_food(i, j); break; case 3: draw_player(i, j); break; default: printf("Error: This point should never be reached."); fflush(stdout); exit(0); break; } } } glFlush(); } void keypress(unsigned char key, int x, int y) { switch(key) { case 'q': exit(0); break; case 'j': if(levelOne[player_y][player_x - 1] != 1) { levelOne[player_y][player_x] = 0; levelOne[player_y][player_x - 1] = 3; player_x = player_x - 1; glutPostRedisplay(); } break; case 'l': if(levelOne[player_y][player_x + 1] != 1) { levelOne[player_y][player_x] = 0; levelOne[player_y][player_x + 1] = 3; player_x = player_x + 1; glutPostRedisplay(); } break; case 'i': if(levelOne[player_y - 1][player_x] != 1) { levelOne[player_y][player_x] = 0; levelOne[player_y - 1][player_x] = 3; player_y = player_y - 1; glutPostRedisplay(); } break; case 'k': if(levelOne[player_y + 1][player_x] != 1) { levelOne[player_y][player_x] = 0; levelOne[player_y + 1][player_x] = 3; player_y = player_y + 1; glutPostRedisplay(); } break; } } void main_menu(int value) { switch(value) { case 1: /* toggle outline/fill */ fillmode = !fillmode; break; case 2: exit(0); } glutPostRedisplay(); } void draw_wall(float i, float j) { if(fillmode) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } /* transform the input into something that OpenGL can use */ float y = ((levelOne_width/2) - i)/(levelOne_width/2); float x = (j - (levelOne_height/2))/(levelOne_height/2); /* draw a blue square at the given location */ glBegin(GL_POLYGON); glColor3fv(blue); glVertex2f(x, y - 0.1); glColor3fv(cyan); glVertex2f(x, y); glColor3fv(white); glVertex2f(x + 0.1, y); glColor3fv(cyan); glVertex2f(x + 0.1, y - 0.1); glEnd(); } void draw_food(float i, float j) { if(fillmode) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } /* transform the input into something that OpenGL can use */ float y = ((levelOne_width/2) - i)/(levelOne_width/2); float x = (j - (levelOne_height/2))/(levelOne_height/2); /* draw a circle at the given location */ glBegin(GL_POLYGON); glColor3fv(red); float pi = 3.1415926535; float counter; for(counter = 0; counter < 2*pi; counter = counter + (pi/6)) { glVertex2f(x + 0.05 + (0.025 * cos(counter)), y - 0.05 + (0.025 * sin(counter))); } glEnd(); } void draw_player(float i, float j) { if(fillmode) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } /* transform the input into something that OpenGL can use */ float y = ((levelOne_width/2) - i)/(levelOne_width/2); float x = (j - (levelOne_height/2))/(levelOne_height/2); /* draw a polygon at the given location */ glBegin(GL_POLYGON); glColor3fv(yellow); glVertex2f(x + 0.05, y - 0.05); float pi = 3.1415926535; float counter; for(counter = (pi/6); counter < ((2*pi)-(pi/6)); counter = counter + (pi/6)) { glVertex2f(x + 0.05 + (0.05 * cos(counter)), y - 0.05 + (0.05 * sin(counter))); } glEnd(); }