From 871fe9ff48215b9f3570e49877e695dbaea01e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Mon, 11 Apr 2016 00:56:22 +0200 Subject: [PATCH] =?UTF-8?q?Mais=20c'est=20la=20mort=20qui=20t'a=20assassin?= =?UTF-8?q?=C3=A9e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/block.hpp | 8 +++++++- include/game.hpp | 8 ++++++++ include/gravity_block.hpp | 2 +- include/level.hpp | 1 + include/object.hpp | 9 ++++++++- include/player.hpp | 8 +++++++- src/block.cpp | 6 +++++- src/game.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/gravity_block.cpp | 4 ++-- src/object.cpp | 4 ++-- src/player.cpp | 7 ++++++- 11 files changed, 86 insertions(+), 10 deletions(-) diff --git a/include/block.hpp b/include/block.hpp index f62a57c..4a5f644 100644 --- a/include/block.hpp +++ b/include/block.hpp @@ -58,7 +58,13 @@ public: /** * Appelé lorsque le bloc est activé par un objet */ - virtual void activated(Level& level, Object* object); + virtual void activate(Level& level, Object* object); + + /** + * Appelé lorsque le bloc a été tué. Si cette fonction + * est appelé, le bloc sera supprimé à la frame suivante + */ + virtual void kill(Game& game); /** * Récupère l'identifiant de type des blocs diff --git a/include/game.hpp b/include/game.hpp index a8057a6..ae5aebc 100644 --- a/include/game.hpp +++ b/include/game.hpp @@ -18,6 +18,8 @@ public: private: WidgetTimer widget_timer; sf::Time next_frame_time; + std::vector pending_kill; + bool test_mode; std::shared_ptr return_state; Mode mode; @@ -28,6 +30,12 @@ private: */ void update(); + /** + * Vérifie si l'objet donné se trouve dans + * la zone de jeu ou non + */ + bool isInZone(Object::Ptr object); + protected: /** * Dessine tous les objets, le fond et diff --git a/include/gravity_block.hpp b/include/gravity_block.hpp index a65a73f..d765e54 100644 --- a/include/gravity_block.hpp +++ b/include/gravity_block.hpp @@ -42,7 +42,7 @@ public: /** * Appelé lorsque le bloc de gravité est activé par un objet */ - virtual void activated(Level& level, Object* object); + virtual void activate(Level& level, Object* object); /** * Récupère l'identifiant de type des blocs de gravité diff --git a/include/level.hpp b/include/level.hpp index bfc12fe..0fe1423 100644 --- a/include/level.hpp +++ b/include/level.hpp @@ -171,6 +171,7 @@ public: * Supprime l'objet donné */ void removeObject(Object::Ptr object); + void removeObject(Object* object); /** * Récupère la zone du niveau diff --git a/include/object.hpp b/include/object.hpp index 15be611..07b5a25 100644 --- a/include/object.hpp +++ b/include/object.hpp @@ -9,6 +9,7 @@ #include "resource_manager.hpp" class Level; +class Game; class Object { public: @@ -78,7 +79,13 @@ public: /** * Appelé lorsque l'objet est activé par un autre */ - virtual void activated(Level& level, Object* object) = 0; + virtual void activate(Level& level, Object* object) = 0; + + /** + * Appelé lorsque l'objet a été tué. Si cette fonction + * est appelé, l'objet sera supprimé à la frame suivante + */ + virtual void kill(Game& game) = 0; /** * Récupère l'identifiant de type de cet objet diff --git a/include/player.hpp b/include/player.hpp index db78397..f9e192d 100644 --- a/include/player.hpp +++ b/include/player.hpp @@ -57,7 +57,13 @@ public: /** * Appelé lorsque le joueur est activé par un objet */ - virtual void activated(Level& level, Object* object); + virtual void activate(Level& level, Object* object); + + /** + * Appelé lorsque le jouer a été tué. Si cette fonction + * est appelé, le joueur sera supprimé à la frame suivante + */ + virtual void kill(Game& game); /** * Récupère l'identifiant de type des joueurs diff --git a/src/block.cpp b/src/block.cpp index da8cb0e..f167b2e 100644 --- a/src/block.cpp +++ b/src/block.cpp @@ -73,12 +73,16 @@ void Block::draw(Level& level) { } } -void Block::activated(Level& level, Object* object) { +void Block::activate(Level& level, Object* object) { // ne rien faire si le bloc est activé. // Ceci est un bloc de base qui n'a pas a réagir // aux activations } +void Block::kill(Game& game) { + // rien à faire de plus si le bloc a été tué +} + sf::FloatRect Block::getAABB() const { return sf::FloatRect( getPosition().x - Constants::GRID / 2, diff --git a/src/game.cpp b/src/game.cpp index 852e9b9..95e20fc 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1,4 +1,5 @@ #include +#include #include "game.hpp" #include "player.hpp" #include "constants.hpp" @@ -120,6 +121,23 @@ void Game::update() { std::vector colliding; std::vector& objects = getObjects(); + // on tue les objets qui étaient déjà planifiés pour mourir + for (auto it = pending_kill.begin(); it != pending_kill.end(); it++) { + removeObject(*it); + } + + pending_kill.empty(); + + // détection des objets en dehors de la zone de jeu + for (auto it = objects.begin(); it != objects.end(); it++) { + if (!isInZone(*it)) { + // l'objet est sorti de la zone, on le signale et on + // planifie sa mort à la prochaine frame + (*it)->kill(*this); + pending_kill.push_back(*it); + } + } + // détection des objets en collision for (unsigned int i = 0; i < objects.size(); i++) { Object::Ptr obj_a = objects[i]; @@ -162,6 +180,27 @@ void Game::update() { } } +/** + * Implémentation tirée de + * http://stackoverflow.com/a/2922778/3452708 + */ +bool Game::isInZone(Object::Ptr object) { + std::vector& zone = getZone(); + sf::Vector2f pos = object->getPosition(); + unsigned int vertices = getZone().size(); + bool result = false; + + for (unsigned int i = 0, j = vertices - 1; i < vertices; j = i++) { + if (((zone[i].y > pos.y) != (zone[j].y > pos.y)) && + (pos.x < (zone[j].x - zone[i].x) * (pos.y - zone[i].y) / + (zone[j].y - zone[i].y) + zone[i].x)) { + result = !result; + } + } + + return result; +} + bool Game::getTestMode() { return test_mode; } diff --git a/src/gravity_block.cpp b/src/gravity_block.cpp index 4ea8b2c..c279914 100644 --- a/src/gravity_block.cpp +++ b/src/gravity_block.cpp @@ -35,8 +35,8 @@ std::string GravityBlock::getTexture() { return texture_name + ".tga"; } -void GravityBlock::activated(Level& level, Object* object) { - Block::activated(level, object); +void GravityBlock::activate(Level& level, Object* object) { + Block::activate(level, object); // lorsque le bloc est activé, il transmet son // sens de gravité au niveau diff --git a/src/object.cpp b/src/object.cpp index 6830643..8c44d45 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -234,8 +234,8 @@ void Object::solveCollision(Level& level, Object::Ptr obj, const sf::Vector2f& n // en ce point, on est bertins qu'une collision a eu lieu. // activation réciproque des deux objets - activated(level, obj.get()); - obj->activated(level, this); + activate(level, obj.get()); + obj->activate(level, this); // on utilise le plus petit coefficient de friction entre les // deux objets comme le coefficient de la collision diff --git a/src/player.cpp b/src/player.cpp index 00b8306..e606a3b 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -1,4 +1,5 @@ #include "player.hpp" +#include "game.hpp" #include "level.hpp" #include "block.hpp" #include "constants.hpp" @@ -89,12 +90,16 @@ void Player::draw(Level& level) { level.getWindow().draw(sprite); } -void Player::activated(Level& level, Object* object) { +void Player::activate(Level& level, Object* object) { // ne rien faire si le joueur est activé. // en règle générale, c'est l'objet activé par le joueur // qui s'occupe de la réponse } +void Player::kill(Game& game) { + game.setMode(Game::Mode::LOST); +} + void Player::updatePosition() { // calcul de la différence de position pour connaître // (approximativement) la rotation de la balle