#include #include "game.hpp" #include "text.hpp" #include "shader.hpp" #include "blockFrame.hpp" #include "texture.hpp" #include "mainMenu.hpp" #include "hotbar.hpp" bool Game::paused; Button Game::continueButton; Button Game::quitButton; bool Game::continu; bool Game::quit; GameMode Game::gameMode; Player Game::player; World Game::world; Game::Game(GLFWwindow* win, std::string _filename){ paused =false; continu = false; quit = false; continueButton = Button("Continue", -0.5, 0.0, 1.0, 0.5); quitButton = Button("Quit", -0.5, -0.5, 1.0, 0.5); filename=_filename; //Load shaders shader=Shader("shaders/vertex_shader.glsl", "shaders/fragment_shader.glsl"); //Load textures blockTexture = createTexture("textures/blockTextures.png"); //We don't want there to be a cursor glfwSetInputMode(win,GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetMouseButtonCallback(win, MousePressed); glfwSetScrollCallback(win, MouseScroll); glfwSetKeyCallback(win, KeyPressed); FILE* f = fopen(filename.c_str(), "rb"); if(f!=NULL){ world.Read(f); fclose(f); }else{ world.clear(); } player.pos = Vector3f(0,1.7,0); world.LoadChunks(ChunkIndex(player.pos)); gameMode=SPECTATOR; } void Game::MouseScroll(GLFWwindow* win, double _, double yoffset){ player.hotbarSelected = mod(player.hotbarSelected+(double)yoffset,9); } void Game::MousePressed(GLFWwindow* win, int button, int action, int mods){ if(paused){ if(action==GLFW_PRESS && button==0){ continu = continueButton.hovering; quit = quitButton.hovering; } }else{ if(action==GLFW_PRESS&&player.isFacingBlock){ if(button==0&&gameMode==CREATIVE) world.SetBlock(player.facingBlock,AIR); if(button==1&&gameMode==CREATIVE) if(player.isAllowedToPlaceBlock(player.newBlock)) world.SetBlock(player.newBlock,(BlockID)player.hotbarSelected); } } } void Game::KeyPressed(GLFWwindow* win, int button, int , int action, int ){ if(button == GLFW_KEY_G && action ==GLFW_PRESS){ if(gameMode==CREATIVE)gameMode=SPECTATOR; else gameMode = CREATIVE; } } void Game::handleInput(GLFWwindow* win){ #define p player static float yaw_start=0; static float pitch_start=0; static int mouse_x_prev; static int mouse_y_prev; //Is only true if it is the first or security time handleInput gets called static bool firstOrSecond = true; //Is only true if it is the first time handleInput gets called static bool first = true; static bool spacePressed = false; static double lastSpaceReleased = -1.0; if(!paused){ if(glfwGetKey(win, GLFW_KEY_W) == GLFW_PRESS){ p.move(Vector3f(0.1*sin(p.yaw),0,0.1*cos(p.yaw)),world, gameMode==SPECTATOR); } if(glfwGetKey(win, GLFW_KEY_S) == GLFW_PRESS){ p.move(Vector3f(-0.1*sin(p.yaw),0,-0.1*cos(p.yaw)),world, gameMode==SPECTATOR); } if(glfwGetKey(win, GLFW_KEY_D) == GLFW_PRESS){ p.move(Vector3f(0.1*cos(p.yaw),0,-0.1*sin(p.yaw)),world, gameMode==SPECTATOR); } if(glfwGetKey(win, GLFW_KEY_A) == GLFW_PRESS){ p.move(Vector3f(-0.1*cos(p.yaw),0,0.1*sin(p.yaw)),world, gameMode==SPECTATOR); } if(glfwGetKey(win, GLFW_KEY_SPACE) == GLFW_RELEASE){ if(spacePressed){ lastSpaceReleased = glfwGetTime(); spacePressed=false; } } if(glfwGetKey(win, GLFW_KEY_SPACE) == GLFW_PRESS){ spacePressed = true; if(gameMode==CREATIVE){ if(glfwGetTime()-lastSpaceReleased<0.3){ if(p.standingMode==Flying) p.standingMode=Falling; else p.standingMode=Flying; } } if(gameMode==SPECTATOR||p.standingMode==Flying){ p.move(Vector3f(0,0.1,0),world, gameMode==SPECTATOR); } else if(p.standingMode==Walking){ p.standingMode=Falling; p.ySpeed = 0.2; } } if(glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS|| glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS ){ //Move downwards p.move(Vector3f(0,-0.1,0),world,gameMode==SPECTATOR); } if(glfwGetKey(win, GLFW_KEY_1)==GLFW_PRESS){ p.hotbarSelected = 0; } if(glfwGetKey(win, GLFW_KEY_2)==GLFW_PRESS){ p.hotbarSelected = 1; } if(glfwGetKey(win, GLFW_KEY_3)==GLFW_PRESS){ p.hotbarSelected = 2; } if(glfwGetKey(win, GLFW_KEY_4)==GLFW_PRESS){ p.hotbarSelected = 3; } if(glfwGetKey(win, GLFW_KEY_5)==GLFW_PRESS){ p.hotbarSelected = 4; } if(glfwGetKey(win, GLFW_KEY_6)==GLFW_PRESS){ p.hotbarSelected = 5; } if(glfwGetKey(win, GLFW_KEY_7)==GLFW_PRESS){ p.hotbarSelected = 6; } if(glfwGetKey(win, GLFW_KEY_8)==GLFW_PRESS){ p.hotbarSelected = 7; } if(glfwGetKey(win, GLFW_KEY_9)==GLFW_PRESS){ p.hotbarSelected = 8; } if(glfwGetKey(win, GLFW_KEY_ESCAPE) == GLFW_PRESS|| glfwGetKey(win, GLFW_KEY_CAPS_LOCK) == GLFW_PRESS){ firstOrSecond=true; first=true; yaw_start=p.yaw; pitch_start=p.pitch; paused=true; glfwSetInputMode(win,GLFW_CURSOR, GLFW_CURSOR_NORMAL); //Tis is necessary for te following reason: When //glfwSetInputMode gets called it also changes //the position of the mouse and thus the yaw and pitch //will also change. We don't want this and therefore we //return return; } double mouse_x,mouse_y; glfwGetCursorPos(win,&mouse_x,&mouse_y); //In the first frame we would set p.yaw and pich to zero and afterwards //we would change these angles according to the movement of the mouse. //For reasons that are not known by me the player does not have //p.yaw=0, p.pitch=0 in the beginning of the game. This is fixed by set p.yaw and //p.pitch to zero in the first and second frame. if(firstOrSecond){ p.yaw=yaw_start; p.pitch =pitch_start; }else{ p.yaw += (float)(mouse_x-mouse_x_prev)/360.0*M_PI; p.pitch += (float)(mouse_y-mouse_y_prev)/360.0*M_PI; //The player is not allowed to be upside down. if(p.pitch>M_PI/2)p.pitch=M_PI/2; if(p.pitch<-M_PI/2)p.pitch = -M_PI/2; } mouse_x_prev=mouse_x; mouse_y_prev=mouse_y; if(first)first=false; else firstOrSecond =false; } } Control* Game::handle(GLFWwindow* win){ if(paused){ continueButton.handle(win); quitButton.handle(win); if(continu){ continu =false; paused=false; glfwSetInputMode(win,GLFW_CURSOR, GLFW_CURSOR_DISABLED); } if(quit){ quit =false; return(new mainMenu(win)); } } if(gameMode==CREATIVE){ player.checkFalling(world); } Vector3f prev_pos=player.pos; handleInput(win); //If the chunk that the player is in has changed //it potentially needs to load in new chunks if(ChunkIndex(prev_pos)!=ChunkIndex(player.pos)){ world.LoadChunks(ChunkIndex(player.pos)); } return NULL; } void Game::draw(float screenRatio){ shader.activate(); Matrix4f transform =PerspectiveProjectionMatrix( 0.001, 800.0, screenRatio)* PitchRotationMatrix(player.pitch)* //Rotate around the X-axis YawRotationMatrix(player.yaw)* //Rotate around the Y-axis TranslationMatrix(-player.pos); //Sends the transformation matrix to the shader shader.setUniformMat4("transform",transform); //Draw all chunks in the neighberhoud of the player world.Draw(player.pos,blockTexture); if(gameMode==CREATIVE){ player.findFacingBlock(&world); BlockFrame frame = BlockFrame(player.facingBlock); frame.Draw(blockTexture); } //Text that gives information about the position and //direction of the player char posText[50]; char dirText[50]; sprintf(posText,"Position: x=%f, y=%f, z=%f", player.pos.x,player.pos.y,player.pos.z); sprintf(dirText,"Direction: yaw=%f, pitch=%f", player.yaw/M_PI*180,player.pitch/M_PI*180); Text font1(posText,Text::LEFT_BOTTOM,0.05,10000.0,-1.0,0.9,screenRatio); Text font2(dirText,Text::LEFT_BOTTOM,0.05,10000.0,-1.0,0.8,screenRatio); Text font3; switch(gameMode){ case(CREATIVE): switch(player.standingMode){ case(Falling): font3 = Text("Creative mode (Falling)",Text::LEFT_BOTTOM,0.05,100000.0, -1.0,0.7,screenRatio); break; case(Walking): font3 = Text("Creative mode (Walking)",Text::LEFT_BOTTOM,0.05,100000.0, -1.0,0.7,screenRatio); break; case(Flying): font3 = Text("Creative mode (Flying)",Text::LEFT_BOTTOM,0.05,100000.0, -1.0,0.7,screenRatio); break; } break; case(SPECTATOR): font3 = Text("Spectator mode",Text::LEFT_BOTTOM,0.05,100000.0, -1.0,0.7,screenRatio); break; } font1.Draw(); font2.Draw(); font3.Draw(); font1.Delete(); font2.Delete(); font3.Delete(); if(gameMode==CREATIVE){ Rectangle middleScreen = Rectangle(-0.05,-0.05,0.1*screenRatio,0.1); middleScreen.Draw(Vector3f(1.0,1.0,1.0)); } if(gameMode==CREATIVE) hotbar.Draw(screenRatio,blockTexture,player.hotbarSelected); if(paused){ continueButton.Draw(screenRatio); quitButton.Draw(screenRatio); } } void Game::shutdown(){ FILE* f = fopen(filename.c_str(), "wb"); if(f==NULL)std::cerr << "Could not open " <