diff --git a/include/states/editor.hpp b/include/states/editor.hpp index 29c684b..b958bf7 100644 --- a/include/states/editor.hpp +++ b/include/states/editor.hpp @@ -74,6 +74,11 @@ private: */ void selectAll(); + /** + * Lance le test du niveau + */ + void test(); + protected: /** * Demande le dessin d'une frame @@ -99,11 +104,6 @@ public: * Traite l'événement donné */ void processEvent(const sf::Event& event) override; - - /** - * Lance le test du niveau - */ - void test(); }; #endif diff --git a/include/states/game.hpp b/include/states/game.hpp index ebd6815..1fdc47a 100644 --- a/include/states/game.hpp +++ b/include/states/game.hpp @@ -43,6 +43,17 @@ private: */ bool isInZone(Object::Ptr object); + /** + * Recommence le niveau depuis le début + */ + void restart(); + + /** + * Échange entre le mode pause et le mode normal + * (si on est dans un autre mode, ne fait rien) + */ + void switchPause(); + protected: /** * Demande le dessin d'une frame @@ -55,11 +66,6 @@ protected: */ void draw() override; - /** - * S'assure que la caméra est centrée sur les joueurs - */ - void ensureCentered(); - public: Game(Manager& manager, bool test = false); virtual ~Game(); diff --git a/include/states/level.hpp b/include/states/level.hpp index ff6a151..9f3b4c2 100644 --- a/include/states/level.hpp +++ b/include/states/level.hpp @@ -20,6 +20,8 @@ class Level : public State { private: sf::View camera; float camera_angle; + sf::Vector2f goal_center; + Utility::Direction gravity_direction; sf::String name; @@ -214,6 +216,16 @@ public: */ void setCamera(sf::View set_camera); + /** + * Récupère la cible de l'animation de la caméra + */ + sf::Vector2f getCenterGoal(); + + /** + * Modifie la cible de l'animation de la caméra + */ + void setCenterGoal(sf::Vector2f set_center); + /** * Récupère le centre de tous les joueurs ou * zéro si aucun joueur diff --git a/res/textures/toolbar/icon_pause.tga b/res/textures/toolbar/icon_pause.tga new file mode 100644 index 0000000..2744cf7 Binary files /dev/null and b/res/textures/toolbar/icon_pause.tga differ diff --git a/res/textures/toolbar/icon_restart.png b/res/textures/toolbar/icon_restart.png new file mode 100644 index 0000000..4e44ba7 Binary files /dev/null and b/res/textures/toolbar/icon_restart.png differ diff --git a/res/textures/toolbar/icon_restart.tga b/res/textures/toolbar/icon_restart.tga new file mode 100644 index 0000000..6ec8ad6 Binary files /dev/null and b/res/textures/toolbar/icon_restart.tga differ diff --git a/src/states/editor.cpp b/src/states/editor.cpp index 0fb895b..cf9cdca 100644 --- a/src/states/editor.cpp +++ b/src/states/editor.cpp @@ -208,7 +208,7 @@ void Editor::processEvent(const sf::Event& event) { // sinon, on déplace la vue else { - sf::View camera = getCamera(); + sf::Vector2f cur_center = getCenterGoal(); // la molette est horizontale ssi. elle l'est vraiment ou // si on utilise la molette verticale et shift @@ -219,18 +219,12 @@ void Editor::processEvent(const sf::Event& event) { ); if (!horizontal) { - camera.move( - sf::Vector2f(0, event.mouseWheelScroll.delta) * - WHEEL_SCROLL_SPEED - ); + cur_center.y += event.mouseWheelScroll.delta * WHEEL_SCROLL_SPEED; } else { - camera.move( - sf::Vector2f(event.mouseWheelScroll.delta, 0) * - WHEEL_SCROLL_SPEED - ); + cur_center.x += event.mouseWheelScroll.delta * WHEEL_SCROLL_SPEED; } - setCamera(camera); + setCenterGoal(cur_center); } } @@ -279,21 +273,21 @@ void Editor::frame() { // scroll de la caméra lorsque la souris se situe sur les bords if (window.hasFocus()) { - sf::View camera = getCamera(); + sf::Vector2f cur_center = getCenterGoal(); sf::Vector2i mouse = sf::Mouse::getPosition(window); // détection du dépassement sur un des 4 bords if (mouse.x < POINTER_SCROLL_PADDING && mouse.x >= -POINTER_SCROLL_PADDING) { - camera.move(sf::Vector2f(-POINTER_SCROLL_SPEED, 0)); + cur_center.x -= POINTER_SCROLL_SPEED; } else if (mouse.x >= window_size.x - POINTER_SCROLL_PADDING && mouse.x < window_size.x + POINTER_SCROLL_PADDING) { - camera.move(sf::Vector2f(POINTER_SCROLL_SPEED, 0)); + cur_center.x += POINTER_SCROLL_SPEED; } else if (mouse.y < POINTER_SCROLL_PADDING && mouse.y >= -POINTER_SCROLL_PADDING) { - camera.move(sf::Vector2f(0, -POINTER_SCROLL_SPEED)); + cur_center.y -= POINTER_SCROLL_SPEED; } else if (mouse.y >= window_size.y - POINTER_SCROLL_PADDING && mouse.y < window_size.y + POINTER_SCROLL_PADDING) { - camera.move(sf::Vector2f(0, POINTER_SCROLL_SPEED)); + cur_center.y += POINTER_SCROLL_SPEED; } - setCamera(camera); + setCenterGoal(cur_center); } // màj du titre de la fenêtre diff --git a/src/states/game.cpp b/src/states/game.cpp index ef87fbc..4bdc23c 100644 --- a/src/states/game.cpp +++ b/src/states/game.cpp @@ -20,7 +20,21 @@ Game::Game(Manager& manager, bool test) : Level(manager), mode(Game::Mode::NORMAL), test(test), next_frame_time(manager.getCurrentTime()), skipped_frames(0), - death_cause(Game::DeathCause::NONE) {} + death_cause(Game::DeathCause::NONE) { + + // ajout des boutons d'action de la barre d'action + if (!isTest()) { + action_toolbar.addButton( + *ResourceManager::get().getImage("toolbar/icon_restart.tga"), + std::bind(&Game::restart, this) + ); + + action_toolbar.addButton( + *ResourceManager::get().getImage("toolbar/icon_pause.tga"), + std::bind(&Game::switchPause, this) + ); + } +} Game::~Game() {} @@ -51,27 +65,29 @@ void Game::processEvent(const sf::Event& event) { Level::processEvent(event); if (event.type == sf::Event::KeyPressed) { - // en mode test, retour, échap et sortie pour revenir à l'éditeur - if (event.key.code == sf::Keyboard::Space || - event.key.code == sf::Keyboard::Escape || - event.key.code == sf::Keyboard::BackSpace) { - getManager().popState(); - return; - } - - // appui sur espace : échange entre le mode pause et normal - if (event.key.code == sf::Keyboard::Space) { - if (getMode() == Game::Mode::NORMAL) { - setMode(Game::Mode::PAUSED); - } else if (getMode() == Game::Mode::PAUSED) { - setMode(Game::Mode::NORMAL); + // en mode test, retour, échap et espace pour revenir à l'éditeur + if (isTest()) { + if (event.key.code == sf::Keyboard::Space || + event.key.code == sf::Keyboard::Escape || + event.key.code == sf::Keyboard::BackSpace) { + getManager().popState(); + } + } else { + // appui sur R : recommencer le niveau + if (event.key.code == sf::Keyboard::R) { + restart(); } - } - // appui sur retour ou échap : sortie - if (event.key.code == sf::Keyboard::Escape || - event.key.code == sf::Keyboard::BackSpace) { - getManager().popState(); + // appui sur espace : échange entre le mode pause et normal + if (event.key.code == sf::Keyboard::Space) { + switchPause(); + } + + // appui sur retour ou échap : sortie + if (event.key.code == sf::Keyboard::Escape || + event.key.code == sf::Keyboard::BackSpace) { + getManager().popState(); + } } } } @@ -125,7 +141,7 @@ void Game::frame() { } // on s'assure que la caméra soit centrée sur nos joueurs - ensureCentered(); + setCenterGoal(getPlayerCenter()); // si on a encore suffisamment de temps, ou si on a sauté // trop de frames, on dessine @@ -151,17 +167,20 @@ void Game::draw() { Level::draw(); } -void Game::ensureCentered() { - sf::View camera = getCamera(); - sf::Vector2f previous_center = camera.getCenter(); - sf::Vector2f new_center = getPlayerCenter(); +void Game::restart() { + load(); - // on anime le centre vers le centre des joueurs - previous_center.x = Utility::animateValue(previous_center.x, 5, new_center.x); - previous_center.y = Utility::animateValue(previous_center.y, 5, new_center.y); + setGravityDirection(Utility::Direction::SOUTH); + setMode(Game::Mode::NORMAL); + setDeathCause(Game::DeathCause::NONE); +} - camera.setCenter(previous_center); - setCamera(camera); +void Game::switchPause() { + if (getMode() == Game::Mode::NORMAL) { + setMode(Game::Mode::PAUSED); + } else if (getMode() == Game::Mode::PAUSED) { + setMode(Game::Mode::NORMAL); + } } void Game::update() { diff --git a/src/states/level.cpp b/src/states/level.cpp index 8c4145c..de80c51 100644 --- a/src/states/level.cpp +++ b/src/states/level.cpp @@ -181,11 +181,14 @@ void Level::load() { setMusic(read_music); setBackground(read_background); - // lecture des objets si une callback a été fournie + // lecture des objets int read_object_count; file.read(reinterpret_cast(&read_object_count), 4); read_object_count = ntohl(read_object_count); + objects.clear(); + players.clear(); + for (int i = 0; i < read_object_count; i++) { char read_object_type; file.read(&read_object_type, 1); @@ -281,7 +284,8 @@ void Level::processEvent(const sf::Event& event) { } void Level::frame() { - sf::Vector2i window_size = (sf::Vector2i) getManager().getWindow().getSize(); + sf::RenderWindow& window = getManager().getWindow(); + sf::Vector2i window_size = (sf::Vector2i) window.getSize(); // mise à jour de l'icône du mute en fonction de l'état sf::Image image; @@ -299,20 +303,27 @@ void Level::frame() { 0, 0, window_size.x, action_toolbar.getHeight() )); -} -void Level::draw() { - sf::RenderWindow& window = getManager().getWindow(); - sf::Vector2u window_size = window.getSize(); + // animation du centre et de la rotation de la caméra + sf::Vector2f cur_center = camera.getCenter(); + + cur_center.x = Utility::animateValue(cur_center.x, 5, goal_center.x); + cur_center.y = Utility::animateValue(cur_center.y, 5, goal_center.y); - // animation de la rotation de la caméra camera_angle = Utility::animateValue( camera_angle, 5, std::fmod((float) gravity_direction * 90, 360) ); + camera.setCenter(cur_center); camera.setRotation(camera_angle + 180); + window.setView(camera); +} + +void Level::draw() { + sf::RenderWindow& window = getManager().getWindow(); + sf::Vector2u window_size = window.getSize(); // efface la scène précédente window.clear(sf::Color(66, 165, 245)); @@ -533,6 +544,11 @@ sf::View Level::getCamera() const { return camera; } +void Level::setCamera(sf::View set_camera) { + camera = set_camera; + goal_center = set_camera.getCenter(); +} + sf::Vector2f Level::pixelToCoords(sf::Vector2i pixel) { sf::RenderWindow& window = getManager().getWindow(); sf::View old_view = window.getView(); @@ -555,8 +571,12 @@ sf::Vector2i Level::coordsToPixel(sf::Vector2f coords) { return pixel; } -void Level::setCamera(sf::View set_camera) { - camera = set_camera; +sf::Vector2f Level::getCenterGoal() { + return goal_center; +} + +void Level::setCenterGoal(sf::Vector2f set_center) { + goal_center = set_center; } sf::Vector2f Level::getPlayerCenter() { diff --git a/src/utility.cpp b/src/utility.cpp index 4fd502e..911fdbe 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -7,7 +7,7 @@ float Utility::animateValue(float current, float speed, float goal) { float diff = gap * Manager::FRAME_TIME.asSeconds() * speed; // si on est très proches de la fin, on termine - if (std::abs(gap) < .05f) { + if (std::abs(gap) < .1f) { return goal; }