#include "maze.h" #include #include #include #include #include "utils.hpp" MazeScreen::MazeScreen(const std::vector>& maze): maze(maze), angleX(0), mouseCapture(false), posX(9999), posZ(9999), solid(true) { for (int i = 0; i < maze.size(); i++) { for (int j = 0; j < maze[i].size(); j++) { if (maze[i][j] == 0 && j < posZ) { posX = i; posZ = j; } } } } void MazeScreen::display() { glClearColor(0.8, 0.8, 0.8, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt( posX, 0, posZ, posX + cos(Utils::toRad(angleX)) * 3, 0, posZ - sin(Utils::toRad(angleX)) * 3, 0, 1, 0 ); for (int i = 0; i < maze.size(); i++) { for (int j = 0; j < maze[i].size(); j++) { // Draw floor glPushMatrix(); glColor3ub(0x33, 0x33, 0x33); glTranslatef(i, -1, j); glutSolidCube(1); glPopMatrix(); float green, blue; switch (maze[i][j]) { case -1: glPushMatrix(); glColor3f(1, 0, 0); glTranslatef(i, 0, j); glutWireCube(1); glPopMatrix(); break; case 1: glPushMatrix(); glTranslatef(i, 0, j); // Scale green by X green = Utils::clamp(Utils::nummap(abs(i - posX), 0, 3, 0, 1), 0, 1); // Scale blue by Z blue = Utils::clamp(Utils::nummap(abs(j - posZ), 0, 3, 0, 1), 0, 1); glColor3f(1, green, blue); glutWireCube(1); if (solid) { glColor3f(1, green, blue); glutSolidCube(1); } glPopMatrix(); break; case 2: glPushMatrix(); glColor3ub(0xee, 0xee, 0x00); glTranslatef(i, -1, j); glutSolidCube(1); glPopMatrix(); break; } } } glFlush(); glutSwapBuffers(); } void MazeScreen::keyboard(unsigned char key, int x, int y) { if (key == '\e') { mouseCapture = false; glutSetCursor(GLUT_CURSOR_INHERIT); } else if (key == ' ') { solid = false; } else if (key == 'w') { forceX += 1; } else if (key == 's') { forceX -= 1; } else if (key == 'a') { forceZ -= 1; } else if (key == 'd') { forceZ += 1; } glutPostRedisplay(); } void MazeScreen::keyboardUp(unsigned char key, int x, int y) { if (key == 'w') { forceX -= 1; } else if (key == 's') { forceX += 1; } else if (key == 'a') { forceZ += 1; } else if (key == 'd') { forceZ -= 1; } else if (key == ' ') { solid = true; } } int gameTime; void MazeScreen::idle() { int newTime = glutGet(GLUT_ELAPSED_TIME); auto deltaTime = (newTime - gameTime) / 1000.0; gameTime = newTime; posX += forceX * deltaTime * cos(Utils::toRad(angleX)) + forceZ * deltaTime * sin(Utils::toRad(angleX)); posZ += forceZ * deltaTime * cos(Utils::toRad(angleX)) - forceX * deltaTime * sin(Utils::toRad(angleX)); glutPostRedisplay(); } void MazeScreen::passiveMotion(int x, int y) { if (mouseCapture) { auto centerX = glutGet(GLUT_WINDOW_WIDTH) / 2; auto centerY = glutGet(GLUT_WINDOW_HEIGHT) / 2; auto diffX = x - centerX; auto diffY = x - centerY; // only left-right movement angleX -= diffX; if (x != centerX || y != centerY) { glutWarpPointer(centerX, centerY); } glutPostRedisplay(); } } void MazeScreen::mouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON) { auto centerX = glutGet(GLUT_WINDOW_WIDTH) / 2; auto centerY = glutGet(GLUT_WINDOW_HEIGHT) / 2; glutWarpPointer(centerX, centerY); mouseCapture = true; glutSetCursor(GLUT_CURSOR_NONE); } else if (button == GLUT_RIGHT_BUTTON) { mouseCapture = false; glutSetCursor(GLUT_CURSOR_INHERIT); } }