/* frogger.c game */ #include #include #include #include #include static GLfloat theta[3], theta0[3] = {115.0, 0.0, 60.0}; static GLdouble m[16]; /* for unproject mouse */ static GLint axis = 2; /* initial viewer location */ static GLdouble viewer[]= {0.0, 0.0, 10.0}; static int winWidth = 600; static int winHeight = 600; static GLfloat speed = 1.0; static GLUquadricObj *log1, *log2, *log3, *log4, *log5; static GLUquadricObj *end1, *end2, *frog1; static GLfloat loglen = 4.0; static GLfloat logr = 1.0; static GLfloat log1x, log1x0 = -14.0; static GLfloat log1y, log1y0 = 7.0; static GLfloat log2x, log2x0 = -11.0; static GLfloat log2y, log2y0 = 3.5; static GLfloat log3x, log3x0 = -9.0; static GLfloat log3y, log3y0 = 0.0; static GLfloat log4x, log4x0 = -8.0; static GLfloat log4y, log4y0 = -3.5; static GLfloat log5x, log5x0 = -7.0; static GLfloat log5y, log5y0 = -7.0; static GLfloat frogx, frogx0 = 0.0; static GLfloat frogy, frogy0 = 11.0; static GLfloat frogz, frogz0 = -0.75; static int frogpos = 0; static void init() { glClearColor(1.0, 1.0, 1.0, 1.0); log1 = gluNewQuadric(); log2 = gluNewQuadric(); log3 = gluNewQuadric(); log4 = gluNewQuadric(); log5 = gluNewQuadric(); end1 = gluNewQuadric(); end2 = gluNewQuadric(); frog1 = gluNewQuadric(); frogx = frogx0; frogy = frogy0; frogz = frogz0; theta[0] = theta0[0]; theta[1] = theta0[1]; theta[2] = theta0[2]; log1x = log1x0; log1y = log1y0; log2x = log2x0; log2y = log2y0; log3x = log3x0; log3y = log3y0; log4x = log4x0; log4y = log4y0; log5x = log5x0; log5y = log5y0; } /* end init */ static void logs() { glColor3f(0.5, 0.0, 0.5); /* brown logs */ glPushMatrix(); glTranslatef( log1x, log1y, 0.0); glRotatef(90.0, 0.0, 1.0, 0.0); gluCylinder(log1, 1.0, 1.0, loglen, 12, 12); gluDisk(end1, 0.0, 1.0, 12, 12); glTranslatef(0.0, 0.0, loglen); gluDisk(end2, 0.0, 1.0, 12, 12); glPopMatrix(); glPushMatrix(); glTranslatef( log2x, log2y, 0.0); glRotatef(90.0, 0.0, 1.0, 0.0); gluCylinder(log2, 1.0, 1.0, loglen, 12, 12); gluDisk(end1, 0.0, 1.0, 12, 12); glTranslatef(0.0, 0.0, loglen); gluDisk(end2, 0.0, 1.0, 12, 12); glPopMatrix(); glPushMatrix(); glTranslatef( log3x, log3y, 0.0); glRotatef(90.0, 0.0, 1.0, 0.0); gluCylinder(log3, 1.0, 1.0, loglen, 12, 12); gluDisk(end1, 0.0, 1.0, 12, 12); glTranslatef(0.0, 0.0, loglen); gluDisk(end2, 0.0, 1.0, 12, 12); glPopMatrix(); glPushMatrix(); glTranslatef( log4x, log4y, 0.0); glRotatef(90.0, 0.0, 1.0, 0.0); gluCylinder(log4, 1.0, 1.0, loglen, 12, 12); gluDisk(end1, 0.0, 1.0, 12, 12); glTranslatef(0.0, 0.0, loglen); gluDisk(end2, 0.0, 1.0, 12, 12); glPopMatrix(); glPushMatrix(); glTranslatef( log5x, log5y, 0.0); glRotatef(90.0, 0.0, 1.0, 0.0); gluCylinder(log5, 1.0, 1.0, loglen, 12, 12); gluDisk(end1, 0.0, 1.0, 12, 12); glTranslatef(0.0, 0.0, loglen); gluDisk(end2, 0.0, 1.0, 12, 12); glPopMatrix(); glColor3f(0.0, 0.0, 1.0); /* blue water*/ glBegin(GL_POLYGON); glVertex3f(-15.0, -10.0, 0.0); glVertex3f(-15.0, 10.0, 0.0); glVertex3f( 15.0, 10.0, 0.0); glVertex3f( 15.0, -10.0, 0.0); glEnd(); glColor3f(0.4, 0.4, 1.0); /* light blue water*/ glBegin(GL_POLYGON); glVertex3f( 15.0, -10.0, 4.0); glVertex3f( 15.0, 10.0, 4.0); glVertex3f( 15.0, 10.0, 0.0); glVertex3f( 15.0, -10.0, 0.0); glEnd(); glColor3f(0.4, 0.4, 1.0); /* upper blue water*/ glBegin(GL_POLYGON); glVertex3f( -15.0, -10.0, -4.0); glVertex3f( -15.0, 10.0, -4.0); glVertex3f( -15.0, 10.0, 0.0); glVertex3f( -15.0, -10.0, 0.0); glEnd(); glColor3f(0.0, 1.0, 0.0); /* green grass*/ glBegin(GL_POLYGON); glVertex3f(-15.0, -12.0, -0.5); glVertex3f(-15.0, -10.0, -0.5); glVertex3f( 15.0, -10.0, -0.5); glVertex3f( 15.0, -12.0, -0.5); glEnd(); glColor3f(0.0, 0.95, 0.0); /* green grass edge*/ glBegin(GL_POLYGON); glVertex3f(-15.0, -10.0, -0.5); glVertex3f(-15.0, -10.0, 0.0); glVertex3f( 15.0, -10.0, 0.0); glVertex3f( 15.0, -10.0, -0.5); glEnd(); glColor3f(0.0, 0.90, 0.0); /* lower green grass*/ glBegin(GL_POLYGON); glVertex3f( 15.0, -12.0, 4.0); glVertex3f( 15.0, -12.0, -0.5); glVertex3f( 15.0, -10.0, -0.5); glVertex3f( 15.0, -10.0, 4.0); glEnd(); glColor3f(0.0, 0.90, 0.0); /* upper green grass*/ glBegin(GL_POLYGON); glVertex3f(-15.0, -12.0, -4.0); glVertex3f(-15.0, -12.0, -0.5); glVertex3f(-15.0, -10.0, -0.5); glVertex3f(-15.0, -10.0, -4.0); glEnd(); glColor3f(1.0, 1.0, 0.0); /* yellow sand*/ glBegin(GL_POLYGON); glVertex3f(-15.0, 12.0, -0.5); glVertex3f(-15.0, 10.0, -0.5); glVertex3f( 15.0, 10.0, -0.5); glVertex3f( 15.0, 12.0, -0.5); glEnd(); glColor3f(0.95, 0.95, 0.0); /* yellow sand edge*/ glBegin(GL_POLYGON); glVertex3f(-15.0, 10.0, -0.5); glVertex3f(-15.0, 10.0, 0.0); glVertex3f( 15.0, 10.0, 0.0); glVertex3f( 15.0, 10.0, -0.5); glEnd(); glColor3f(0.90, 0.90, 0.0); /* lower yellow sand*/ glBegin(GL_POLYGON); glVertex3f( 15.0, 12.0, 4.0); glVertex3f( 15.0, 12.0, -0.5); glVertex3f( 15.0, 10.0, -0.5); glVertex3f( 15.0, 10.0, 4.0); glEnd(); glColor3f(0.90, 0.90, 0.0); /* upper yellow sand*/ glBegin(GL_POLYGON); glVertex3f(-15.0, 12.0, -4.0); glVertex3f(-15.0, 12.0, -0.5); glVertex3f(-15.0, 10.0, -0.5); glVertex3f(-15.0, 10.0, -4.0); glEnd(); } /* end logs */ static void frog() { glColor3f(0.0, 0.7, 0.0); /* frog*/ glPushMatrix(); glTranslatef( frogx, frogy, frogz); gluSphere(frog1, 0.5, 12, 12); glPopMatrix(); } /* end frog */ static void gator() { } /* end gator */ static void drawText(void) { char msg1[] = "'XxYyZz' for axis rotation 'F' or 'f' for speed"; char msg2[] = "thX= thY= thZ= "; char msg3[] = "mouse button for frog to jump, 'r' for reset"; int i, len; /* Draw text */ sprintf(&msg2[5],"%4.0f", theta[0]); msg2[9] = ','; sprintf(&msg2[17],"%4.0f", theta[1]); msg2[21] = ','; sprintf(&msg2[29],"%4.0f", theta[2]); msg2[33] = ','; glEnable(GL_LINE_SMOOTH); /* glBlendFunc(GL_ONE, GL_ONE); */ glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, winWidth, 0, winHeight, -1, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glColor4f(0.0, 0.0, 1.0, 1.0); glRasterPos2i(10, 10); len = strlen(msg1); for (i=0; i 13.0) {log1x = log1x - 31.0; base = base*1.5;} if(frogpos == 1) frogx = frogx + base*speed; log2x = log2x + 0.95*base*speed; if(log2x > 13.0) log2x = log2x - 31.0; if(frogpos == 2) frogx = frogx + 0.95*base*speed; log3x = log3x + 0.9*base*speed; if(log3x > 13.0) log3x = log3x - 31.0; if(frogpos == 3) frogx = frogx + 0.9*base*speed; log4x = log4x + 0.85*base*speed; if(log4x > 13.0) log4x = log4x - 31.0; if(frogpos == 4) frogx = frogx + 0.85*base*speed; log5x = log5x + 0.8*base*speed; if(log5x > 13.0) log5x = log5x - 31.0; if(frogpos == 5) frogx = frogx + 0.8*base*speed; if(frogx > 15.0) /* reset to start */ { frogpos = 0; frogx = frogx0; frogy = frogy0; frogz = frogz0; } glutPostRedisplay(); } /* end move_logs */ static GLdouble dist(GLdouble a1x, GLdouble a1y, GLdouble a1z, GLdouble a2x, GLdouble a2y, GLdouble a2z, GLdouble a3x, GLdouble a3y, GLdouble a3z) { GLdouble d, ax, ay, az, bx, by, bz, cx, cy, cz; ax = a2x-a1x; ay = a2y-a1y; az = a2z-a1z; bx = a1x-a3x; by = a1y-a3y; bz = a1z-a3z; cx = ay*bz-az*by; cy = ax*bz-az*bx; cz = ax*by-ay*bx; d = sqrt(cx*cx+cy*cy+cz*cz)/sqrt(ax*ax+ay*ay+az*az); return d; } /* end dist */ static GLdouble dist2(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) { return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } /* end dist2 */ /* When the left mouse button is pressed, the x,y mouse position is used */ /* to find two 3D points, one at near, one at far. The line joining these */ /* points is used to find the closest world point. */ static void mouse(int button, int state, int x, int y) { GLint viewport[4]; GLdouble projmatrix[16]; /* modelview matrix m is global */ GLint realy; /* OpenGL y coordinate position */ GLdouble wx0, wy0, wz0; /* returned world x, y, z coords at near */ GLdouble wx1, wy1, wz1; /* returned world x, y, z coords at far */ GLdouble dlog, dfrog; GLdouble jump = 7.0; int i; if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { glGetIntegerv (GL_VIEWPORT, viewport); glGetDoublev(GL_PROJECTION_MATRIX, projmatrix); /* note viewport[3] is height of window in pixels */ realy = viewport[3] - (GLint) y - 1; gluUnProject((GLdouble) x, (GLdouble) realy, 0.0, m, projmatrix, viewport, &wx0, &wy0, &wz0); gluUnProject((GLdouble) x, (GLdouble) realy, 1.0, m, projmatrix, viewport, &wx1, &wy1, &wz1); if(frogpos == 6) { dlog = dist(wx0, wy0, wz0, wx1, wy1, wz1, frogx, frogy, frogz); if(dlog < 2.0) { frogpos = 0; frogx = frogx0; frogy = frogy0; frogz = frogz0; } } if(frogpos == 5) { frogpos = 6; /* frogx = frogx0; */ frogy = -frogy0; frogz = frogz0; } if(frogpos == 4) { dlog = dist(wx0, wy0, wz0, wx1, wy1, wz1, log5x+loglen/2.0, log5y, 0.0); dfrog = dist2(frogx, frogy, log5x+loglen/2.0, log5y); printf("mouse to log %d is %g, to frog is %g \n", 1, dlog, dfrog); if(dlog < 2.0 && dfrog < jump) { frogx = log5x+loglen/2.0; frogy = log5y; frogz = -1.5; frogpos = 5; } } if(frogpos == 3) { dlog = dist(wx0, wy0, wz0, wx1, wy1, wz1, log4x+loglen/2.0, log4y, 0.0); dfrog = dist2(frogx, frogy, log4x+loglen/2.0, log4y); printf("mouse to log %d is %g, to frog is %g \n", 4, dlog, dfrog); if(dlog < 2.0 && dfrog < jump) { frogx = log4x+loglen/2.0; frogy = log4y; frogz = -1.5; frogpos = 4; } } if(frogpos == 2) { dlog = dist(wx0, wy0, wz0, wx1, wy1, wz1, log3x+loglen/2.0, log3y, 0.0); dfrog = dist2(frogx, frogy, log3x+loglen/2.0, log3y); printf("mouse to log %d is %g, to frog is %g \n", 3, dlog, dfrog); if(dlog < 2.0 && dfrog < jump) { frogx = log3x+loglen/2.0; frogy = log3y; frogz = -1.5; frogpos = 3; } } if(frogpos == 1) { dlog = dist(wx0, wy0, wz0, wx1, wy1, wz1, log2x+loglen/2.0, log2y, 0.0); dfrog = dist2(frogx, frogy, log2x+loglen/2.0, log2y); printf("mouse to log %d is %g, to frog is %g \n", 2, dlog, dfrog); if(dlog < 2.0 && dfrog < jump) { frogx = log2x+loglen/2.0; frogy = log2y; frogz = -1.5; frogpos = 2; } } if(frogpos == 0) { dlog = dist(wx0, wy0, wz0, wx1, wy1, wz1, log1x+loglen/2.0, log1y, 0.0); dfrog = dist2(frogx, frogy, log1x+loglen/2.0, log1y); printf("mouse to log %d is %g, to frog is %g \n", 1, dlog, dfrog); if(dlog < 2.0 && dfrog < jump) { frogx = log1x+loglen/2.0; frogy = log1y; frogz = -1.5; frogpos = 1; } } } } /* end mouse */ static void keys(unsigned char key, int x, int y) { /* Use x, X, y, Y, z, and Z keys to move viewer */ if(key == 'x') theta[0]-= 5.0; if(key == 'X') theta[0]+= 5.0; if(key == 'y') theta[1]-= 5.0; if(key == 'Y') theta[1]+= 5.0; if(key == 'z') theta[2]-= 5.0; if(key == 'Z') theta[2]+= 5.0; if(key == 'l') log1x = log1x+0.5; if(key == 'm') log1y = log1y+0.5; if(key == 'f') speed = speed*0.75; if(key == 'F') speed = speed*1.25; if(key == 'r') init(); /* reset */ glutPostRedisplay(); } /* end keys */ static void myReshape(int w, int h) { winWidth = w; winHeight = h; glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w <= h) glOrtho(-15.0, 15.0, -15.0 * (GLfloat)h / (GLfloat)w, 15.0 * (GLfloat)h / (GLfloat)w, -24.0, 24.0); else glOrtho(-15.0 * (GLfloat)w / (GLfloat)h, 15.0 * (GLfloat)w / (GLfloat)h, -15.0, 15.0, -24.0, 24.0); glMatrixMode(GL_MODELVIEW); } /* end myReshape */ int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(winWidth, winHeight); glutCreateWindow(argv[0]); glutReshapeFunc(myReshape); glutDisplayFunc(display); glutMouseFunc(mouse); glutKeyboardFunc(keys); glutIdleFunc(move_logs); glEnable(GL_DEPTH_TEST); init(); glutMainLoop(); return 0; } /* end main of frogger.c */