diff --git a/include/block.hpp b/include/block.hpp index 7dedbfb..4081da6 100644 --- a/include/block.hpp +++ b/include/block.hpp @@ -36,7 +36,7 @@ public: /** * Appelé lorsque le bloc est activé par un objet */ - virtual void activated(Object& object); + virtual void activated(Level& level, Object& object); /** * Récupère l'identifiant de type des blocs diff --git a/include/gravity_block.hpp b/include/gravity_block.hpp new file mode 100644 index 0000000..199f341 --- /dev/null +++ b/include/gravity_block.hpp @@ -0,0 +1,51 @@ +#ifndef __PTF_GRAVITY_BLOCK_HPP__ +#define __PTF_GRAVITY_BLOCK_HPP__ + +#include "block.hpp" +#include "level.hpp" + +class GravityBlock : public Block { +private: + GravityDirection gravity_direction; + +public: + /** + * Identifiant unique du type "bloc de gravité" + */ + static const unsigned int TYPE_ID; + + GravityBlock(); + virtual ~GravityBlock(); + + /** + * Clone ce bloc de gravité en un bloc de gravité avec les mêmes propriétés + */ + virtual ObjectPtr clone() const; + + /** + * Appelé lorsque le bloc de gravité est activé par un objet + */ + virtual void activated(Level& level, Object& object); + + /** + * Récupère l'identifiant de type des blocs de gravité + */ + virtual unsigned int getTypeId() const; + + /** + * Chargement du bloc de gravité depuis le fichier donné + */ + static ObjectPtr load(std::ifstream& file); + + /** + * Récupère la direction de gravité du bloc changeur de gravité + */ + GravityDirection getGravityDirection() const; + + /** + * Modifie la direction de gravité du bloc + */ + void setGravityDirection(GravityDirection set_gravity_direction); +}; + +#endif diff --git a/include/level.hpp b/include/level.hpp index 3bdb22d..9a8d67e 100644 --- a/include/level.hpp +++ b/include/level.hpp @@ -115,7 +115,7 @@ public: /** * Modifie la direction de la gravité */ - void setGravity(GravityDirection direction); + void setGravityDirection(GravityDirection direction); /** * Récupère la liste des objets diff --git a/include/object.hpp b/include/object.hpp index 61e8e0f..5757e4a 100644 --- a/include/object.hpp +++ b/include/object.hpp @@ -66,7 +66,7 @@ public: /** * Appelé lorsque l'objet est activé par un autre */ - virtual void activated(Object& object) = 0; + virtual void activated(Level& level, Object& object) = 0; /** * Récupère l'identifiant de type de cet objet @@ -102,7 +102,7 @@ public: * et l'objet passé en paramètre selon la normale * donnée */ - virtual void solveCollision(Object& obj, const sf::Vector2f& normal); + virtual void solveCollision(Level& level, Object& obj, const sf::Vector2f& normal); /** * Application de la correction positionnelle sur diff --git a/include/player.hpp b/include/player.hpp index 36ec109..b37a226 100644 --- a/include/player.hpp +++ b/include/player.hpp @@ -42,7 +42,7 @@ public: /** * Appelé lorsque le joueur est activé par un objet */ - virtual void activated(Object& object); + virtual void activated(Level& level, Object& object); /** * Récupère l'identifiant de type des joueurs diff --git a/levels/level1.dat b/levels/level1.dat index 9093f3b..72e63c0 100644 Binary files a/levels/level1.dat and b/levels/level1.dat differ diff --git a/src/block.cpp b/src/block.cpp index a62f05b..acd7c2a 100644 --- a/src/block.cpp +++ b/src/block.cpp @@ -37,7 +37,7 @@ void Block::draw(Level& level) { ResourceManager& resources = level.getResourceManager(); sf::RenderWindow& window = level.getWindow(); - sprite.setTexture(resources.getTexture("block.png")); + sprite.setTexture(resources.getTexture("block.tga")); select_sprite.setTexture(resources.getTexture("block_select.png")); // coloration du bloc en fonction de sa charge @@ -59,7 +59,7 @@ void Block::draw(Level& level) { } } -void Block::activated(Object& object) { +void Block::activated(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 diff --git a/src/collision.cpp b/src/collision.cpp index 87ee419..18c49ce 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -1,6 +1,7 @@ #include "collision.hpp" #include "player.hpp" #include "block.hpp" +#include "gravity_block.hpp" #include "object.hpp" #include #include @@ -189,10 +190,15 @@ std::map< std::pair, std::function > collision_map = { - {std::make_pair(Player::TYPE_ID, Block::TYPE_ID), playerToBlock}, - {std::make_pair(Block::TYPE_ID, Player::TYPE_ID), blockToPlayer}, {std::make_pair(Player::TYPE_ID, Player::TYPE_ID), playerToPlayer}, - {std::make_pair(Block::TYPE_ID, Block::TYPE_ID), blockToBlock} + {std::make_pair(Player::TYPE_ID, Block::TYPE_ID), playerToBlock}, + {std::make_pair(Player::TYPE_ID, GravityBlock::TYPE_ID), playerToBlock}, + {std::make_pair(Block::TYPE_ID, Block::TYPE_ID), blockToBlock}, + {std::make_pair(Block::TYPE_ID, GravityBlock::TYPE_ID), blockToBlock}, + {std::make_pair(Block::TYPE_ID, Player::TYPE_ID), blockToPlayer}, + {std::make_pair(GravityBlock::TYPE_ID, Block::TYPE_ID), blockToBlock}, + {std::make_pair(GravityBlock::TYPE_ID, GravityBlock::TYPE_ID), blockToBlock}, + {std::make_pair(GravityBlock::TYPE_ID, Player::TYPE_ID), blockToPlayer} }; CollisionData::CollisionData(Object& objA, Object& objB) : diff --git a/src/editor.cpp b/src/editor.cpp index 21149ce..d032381 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -18,9 +18,16 @@ Editor::Editor(Manager& manager) : Level(manager), drag_mode(DragMode::NONE), setTotalTime(30); ResourceManager& resources = getResourceManager(); - std::shared_ptr basic = widget_selector.addCategory("BASE"); - basic->addItem("Block", resources.getTexture("block.png")); - basic->addItem("Player", resources.getTexture("player.tga")); + + std::shared_ptr basic_cat = widget_selector.addCategory("BASE"); + basic_cat->addItem("Block", resources.getTexture("block.tga")); + basic_cat->addItem("Player", resources.getTexture("player.tga")); + + std::shared_ptr gravity_cat = widget_selector.addCategory(sf::String(L"GRAVITÉ")); + gravity_cat->addItem("GravityN", resources.getTexture("gravity_block_north.tga")); + gravity_cat->addItem("GravityE", resources.getTexture("gravity_block_east.tga")); + gravity_cat->addItem("GravityS", resources.getTexture("gravity_block_south.tga")); + gravity_cat->addItem("GravityW", resources.getTexture("gravity_block_west.tga")); } Editor::~Editor() {} diff --git a/src/game.cpp b/src/game.cpp index 459d7a1..7d11f82 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -111,7 +111,7 @@ void Game::update() { // résolution des collisions détectées for (unsigned int i = 0; i < colliding.size(); i++) { CollisionData& collided = colliding[i]; - collided.objA.solveCollision(collided.objB, collided.normal); + collided.objA.solveCollision(*this, collided.objB, collided.normal); } // intégration de la vitesse dans la position diff --git a/src/gravity_block.cpp b/src/gravity_block.cpp new file mode 100644 index 0000000..3b19adc --- /dev/null +++ b/src/gravity_block.cpp @@ -0,0 +1,47 @@ +#include "gravity_block.hpp" +#include "level.hpp" + +const unsigned int GravityBlock::TYPE_ID = 3; + +GravityBlock::GravityBlock() : Block() {} +GravityBlock::~GravityBlock() {} + +ObjectPtr GravityBlock::clone() const { + return ObjectPtr(new GravityBlock(*this)); +} + +void GravityBlock::activated(Level& level, Object& object) { + Block::activated(level, object); + + // lorsque le bloc est activé, il transmet son + // sens de gravité au niveau + level.setGravityDirection(gravity_direction); +} + +unsigned int GravityBlock::getTypeId() const { + return TYPE_ID; +} + +ObjectPtr GravityBlock::load(std::ifstream& file) { + ObjectPtr object = ObjectPtr(new GravityBlock); + std::shared_ptr block = std::dynamic_pointer_cast(object); + + // lecture de la direction de la gravité + char gravity_direction; + file.read(&gravity_direction, 1); + block->setGravityDirection((GravityDirection) gravity_direction); + + // lecture des propriétés communes des objets + Object::load(file, object); + file.seekg(1, file.cur); + + return object; +} + +GravityDirection GravityBlock::getGravityDirection() const { + return gravity_direction; +} + +void GravityBlock::setGravityDirection(GravityDirection set_gravity_direction) { + gravity_direction = set_gravity_direction; +} diff --git a/src/level.cpp b/src/level.cpp index fe6ea32..d669660 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -1,11 +1,12 @@ #include "constants.hpp" -#include "block.hpp" +#include "level.hpp" #include "player.hpp" +#include "block.hpp" +#include "gravity_block.hpp" #include #include #include #include -#include "level.hpp" const float GRAVITY = 235; @@ -16,7 +17,8 @@ const float GRAVITY = 235; */ std::map> object_type_map = { {Player::TYPE_ID, Player::load}, - {Block::TYPE_ID, Block::load} + {Block::TYPE_ID, Block::load}, + {GravityBlock::TYPE_ID, GravityBlock::load} }; Level::Level(Manager& manager) : View(manager), gravity(0, GRAVITY) {} @@ -196,21 +198,21 @@ sf::Vector2f Level::getGravity() const { return gravity; } -void Level::setGravity(GravityDirection direction) { +void Level::setGravityDirection(GravityDirection direction) { switch (direction) { case GravityDirection::NORTH: gravity = sf::Vector2f(0, -GRAVITY); break; - case GravityDirection::WEST: + case GravityDirection::EAST: gravity = sf::Vector2f(GRAVITY, 0); break; case GravityDirection::SOUTH: - gravity = sf::Vector2f(0, GRAVITY); + gravity = sf::Vector2f(0, -GRAVITY); break; - case GravityDirection::EAST: + case GravityDirection::WEST: gravity = sf::Vector2f(-GRAVITY, 0); break; } diff --git a/src/object.cpp b/src/object.cpp index 474d7c2..3f1b17c 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -154,7 +154,7 @@ bool Object::detectCollision(const Object& obj, CollisionData& data) const { return getCollisionData(data); } -void Object::solveCollision(Object& obj, const sf::Vector2f& normal) { +void Object::solveCollision(Level& level, Object& obj, const sf::Vector2f& normal) { // si les deux objets sont de masse infinie, réinitialisation // des vitesses en tant que collision if (getMassInvert() == 0 && obj.getMassInvert() == 0) { @@ -174,8 +174,8 @@ void Object::solveCollision(Object& obj, const sf::Vector2f& normal) { // en ce point, on est bertins qu'une collision a eu lieu. // activation réciproque des deux objets - activated(obj); - obj.activated(*this); + activated(level, obj); + obj.activated(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 a9114d4..56cfd95 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -86,7 +86,7 @@ void Player::draw(Level& level) { level.getWindow().draw(sprite); } -void Player::activated(Object& object) { +void Player::activated(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 diff --git a/src/util/widget_selector.cpp b/src/util/widget_selector.cpp index 0526528..b2200bc 100644 --- a/src/util/widget_selector.cpp +++ b/src/util/widget_selector.cpp @@ -63,6 +63,8 @@ void WidgetSelector::draw(sf::Vector2f position, sf::Vector2f size) { background.setPosition(position); window.draw(background); + float total_y = PADDING; + for (unsigned int i = 0; i < categories.size(); i++) { std::shared_ptr category = categories[i]; @@ -75,22 +77,25 @@ void WidgetSelector::draw(sf::Vector2f position, sf::Vector2f size) { category_label.setColor(sf::Color::Black); category_label.setPosition(position + sf::Vector2f( floor(size.x / 2 - category_label.getGlobalBounds().width / 2), - PADDING + total_y )); window.draw(category_label); for (unsigned int j = 0; j < category->items.size(); j++) { + total_y += PADDING + 24; + std::shared_ptr item = category->items[j]; sf::Vector2f sprite_position = position + sf::Vector2f( size.x / 2 - item->sprite.getGlobalBounds().width / 2, - PADDING + 24 + 38 * j + total_y ); // affichage du sprite de l'item item->sprite.setPosition(sprite_position); window.draw(item->sprite); } - } + total_y += 64; + } }