diff --git a/AimGL/resources/Textures/pause.png b/AimGL/resources/Textures/pause.png new file mode 100644 index 0000000..3ad44a9 Binary files /dev/null and b/AimGL/resources/Textures/pause.png differ diff --git a/AimGL/src/CMakeLists_Sources.txt b/AimGL/src/CMakeLists_Sources.txt index b8eb52c..a725bf5 100644 --- a/AimGL/src/CMakeLists_Sources.txt +++ b/AimGL/src/CMakeLists_Sources.txt @@ -24,6 +24,7 @@ set(PROJECT_SOURCES States/CustomStates/LogoState.cpp States/CustomStates/ExitGameState.cpp States/CustomStates/GameState.cpp + States/CustomStates/PauseState.cpp Player/Player.cpp World/Camera.cpp World/InfiniteGridFloor.cpp diff --git a/AimGL/src/Game.cpp b/AimGL/src/Game.cpp index b5dd81c..33548d8 100644 --- a/AimGL/src/Game.cpp +++ b/AimGL/src/Game.cpp @@ -2,6 +2,7 @@ #include "States/CustomStates/ExitGameState.h" #include "States/CustomStates/GameState.h" #include "States/CustomStates/LogoState.h" +#include "States/CustomStates/PauseState.h" #include "Utils/Mouse.h" #include "constants.h" #include "pch.h" @@ -70,6 +71,7 @@ Game::Game() mAppStack.saveState(State_ID::LogoState, *mGameWindow); mAppStack.saveState(State_ID::ExitGameState); mAppStack.saveState(State_ID::GameState, *mGameWindow); + mAppStack.saveState(State_ID::PauseState, *mGameWindow); // Initial state of the statestack is TitleState mAppStack.push(State_ID::LogoState); diff --git a/AimGL/src/States/CustomStates/GameState.cpp b/AimGL/src/States/CustomStates/GameState.cpp index 82a5e0f..b81e1ea 100644 --- a/AimGL/src/States/CustomStates/GameState.cpp +++ b/AimGL/src/States/CustomStates/GameState.cpp @@ -64,6 +64,12 @@ bool GameState::update(const float& deltaTime) bool GameState::handleEvent(const sf::Event& event) { MTR_SCOPE("GameState", "GameState::handleEvent"); + Mouse::handleFirstPersonBehaviour(event, mWindow); + if (not Mouse::isMouseLocked()) + { + return true; + } + mPlayer.handleEvent(event); mShootingRange.handleEvent(event); mSidewayMovingTargetsRange.handleEvent(event); @@ -72,13 +78,13 @@ bool GameState::handleEvent(const sf::Event& event) { switch (event.key.code) { - case sf::Keyboard::Escape: Mouse::unlockMouse(mWindow); break; + case sf::Keyboard::Escape: requestPush(State_ID::PauseState); break; case sf::Keyboard::F1: switchWireframe(); break; case sf::Keyboard::F2: switchDrawingColliders(); break; case sf::Keyboard::F3: switchDrawingImgui(); break; + case sf::Keyboard::F4: Mouse::unlockMouse(mWindow); break; } } - Mouse::handleFirstPersonBehaviour(event, mWindow); return true; } @@ -153,7 +159,6 @@ bool GameState::updateImGui(const float& deltaTime) updateImguiDebugMenu(); updateImGuiDebugInstructionText(); } - mInfiniteGridFloor.showDebugImGui(); } return true; } diff --git a/AimGL/src/States/CustomStates/PauseState.cpp b/AimGL/src/States/CustomStates/PauseState.cpp new file mode 100644 index 0000000..5132420 --- /dev/null +++ b/AimGL/src/States/CustomStates/PauseState.cpp @@ -0,0 +1,60 @@ +#include "PauseState.h" +#include "Utils/Mouse.h" +#include "pch.h" + +PauseState::PauseState(StateStack& stack, WindowToRender& window) + : State(stack) + , mWindowToRender(window) + , mRenderer(window) + , mPauseTextTexture("resources/Textures/pause.png") + , mPauseText(mPauseTextTexture) + , mRectangle({window.getSize().x, window.getSize().y}, {0.f, 0.f, 0.f, 1.f}) + , mWasMouseLocked(Mouse::isMouseLocked()) + +{ + mPauseText.setPosition( + glm::vec2(mWindowToRender.getSize().x / 2.f, mWindowToRender.getSize().y / 2.f), + Sprite2D::Origin::Center); + mPauseText.setHeight(mWindowToRender.getSize().y / 3.f); + mRectangle.setPosition({0, 0}); + mRectangle.setOpacity(0.7f); + Mouse::unlockMouse(window); +} + +void PauseState::draw(sf::Window& target) const +{ + MTR_SCOPE("PauseState", "PauseState::draw"); + mRectangle.draw(mRenderer); + mPauseText.draw(mRenderer); +} + +bool PauseState::update(const float& deltaTime) +{ + MTR_SCOPE("PauseState", "PauseState::update"); + return false; +} + +bool PauseState::fixedUpdate(const float& deltaTime) +{ + MTR_SCOPE("PauseState", "PauseState::fixedUpdate"); + return false; +} + +bool PauseState::handleEvent(const sf::Event& event) +{ + MTR_SCOPE("PauseState", "PauseState::handleEvent"); + if (event.type == sf::Event::KeyPressed) + { + switch (event.key.code) + { + case sf::Keyboard::Escape: + if (mWasMouseLocked) + { + Mouse::lockMouseAtCenter(mWindowToRender); + } + requestPop(); + break; + } + } + return false; +} \ No newline at end of file diff --git a/AimGL/src/States/CustomStates/PauseState.h b/AimGL/src/States/CustomStates/PauseState.h new file mode 100644 index 0000000..99be38d --- /dev/null +++ b/AimGL/src/States/CustomStates/PauseState.h @@ -0,0 +1,50 @@ +#pragma once +#include "States/State.h" + +#include "Game.h" +#include "Renderer/Graphics/2D/Rectangle2D.h" +#include "Renderer/Graphics/2D/Sprite2D.h" +#include "Renderer/Graphics/Texture.h" + +class StateStack; + +/** + * @brief The state in which the player pauses the game + */ +class PauseState : public State +{ +public: + PauseState(StateStack& stack, WindowToRender& window); + + /** + * \brief Draws only this state to the passed target + * \param target where it should be drawn to + */ + void draw(sf::Window& target) const override; + + /** + * \brief Updates the state logic at equal intervals independent of the frame rate. + * \param deltaTime Time interval + */ + bool fixedUpdate(const float& deltaTime) override; + + /** + * \brief Updates the game logic dependent, or independent of time, every rendered frame. + * \param deltaTime the time that has passed since the game was last updated. + */ + bool update(const float& deltaTime) override; + + /** + * \brief It takes input (event) from the user and interprets it + * \param event user input + */ + bool handleEvent(const sf::Event& event) override; + +private: + WindowToRender& mWindowToRender; + Renderer mRenderer; + Texture mPauseTextTexture; + Sprite2D mPauseText; + Rectangle2D mRectangle; + bool mWasMouseLocked; +}; \ No newline at end of file