From 61a0122a019f12f80f880b5dce5ca89a94afd860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Sun, 10 Apr 2016 05:10:27 +0200 Subject: [PATCH] =?UTF-8?q?On=20apprend=20=C3=A0=20se=20servir=20des=20poi?= =?UTF-8?q?nteurs=20peut-=C3=AAtre=20=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/block.hpp | 2 +- include/object.hpp | 2 +- include/player.hpp | 2 +- include/resource_manager.hpp | 19 +++++++++--------- src/block.cpp | 6 +++--- src/collision.cpp | 34 +++++++++++++++---------------- src/editor.cpp | 6 +++--- src/level.cpp | 39 ++++++++++++++++++------------------ src/object.cpp | 2 +- src/player.cpp | 19 +++++++++--------- src/resource_manager.cpp | 38 +++++++++++++++++------------------ 11 files changed, 85 insertions(+), 84 deletions(-) diff --git a/include/block.hpp b/include/block.hpp index 3c86f4b..d12f63f 100644 --- a/include/block.hpp +++ b/include/block.hpp @@ -28,7 +28,7 @@ public: /** * Récupère la boîte englobante du bloc */ - virtual std::unique_ptr getAABB() const; + virtual sf::FloatRect getAABB() const; /** * Récupère le rayon du bloc diff --git a/include/object.hpp b/include/object.hpp index 969766e..ff472cf 100644 --- a/include/object.hpp +++ b/include/object.hpp @@ -56,7 +56,7 @@ public: /** * Récupère la boîte englobante de l'objet */ - virtual std::unique_ptr getAABB() const = 0; + virtual sf::FloatRect getAABB() const = 0; /** * Récupère le rayon de l'objet diff --git a/include/player.hpp b/include/player.hpp index c72c988..1ea300b 100644 --- a/include/player.hpp +++ b/include/player.hpp @@ -32,7 +32,7 @@ public: /** * Récupère la boîte englobante du joueur */ - virtual std::unique_ptr getAABB() const; + virtual sf::FloatRect getAABB() const; /** * Récupère le rayon du joueur diff --git a/include/resource_manager.hpp b/include/resource_manager.hpp index e7020cc..90b9d39 100644 --- a/include/resource_manager.hpp +++ b/include/resource_manager.hpp @@ -8,15 +8,18 @@ #include #include -typedef std::unique_ptr LevelReader; -typedef std::unique_ptr LevelWriter; - +/** + * Gestionnaire de ressources du jeu. Conserve des + * références vers toutes les ressources pour éviter + * de les charger deux fois, permet l'accès uniforme + * aux ressources + */ class ResourceManager { private: std::string resources_dir; - std::unordered_map textures; - std::unordered_map fonts; + std::unordered_map> textures; + std::unordered_map> fonts; float music_volume; sf::Music music; @@ -41,15 +44,13 @@ public: /** * Récupère un lecteur de fichier vers le niveau donné - * (penser à refermer après usage) */ - LevelReader getLevelReader(std::string name); + std::ifstream getLevelReader(std::string name); /** * Récupère un jacob de fichier vers le niveau donné - * (penser à refermer après usage) */ - LevelWriter getLevelWriter(std::string name); + std::ofstream getLevelWriter(std::string name); /** * Démarre la musique de fond donnée diff --git a/src/block.cpp b/src/block.cpp index 7a47d1e..3d8b075 100644 --- a/src/block.cpp +++ b/src/block.cpp @@ -71,12 +71,12 @@ void Block::activated(Level& level, Object& object) { // aux activations } -std::unique_ptr Block::getAABB() const { - return std::unique_ptr(new sf::FloatRect( +sf::FloatRect Block::getAABB() const { + return sf::FloatRect( getPosition().x - Constants::GRID / 2, getPosition().y - Constants::GRID / 2, Constants::GRID, Constants::GRID - )); + ); } float Block::getRadius() const { diff --git a/src/collision.cpp b/src/collision.cpp index fc67eab..058eb4a 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -18,26 +18,26 @@ bool circleToAABB(CollisionData& data) { // recherche du point le plus proche du centre du cercle // sur le rectangle. On regarde la position relative du cercle // par rapport au rectangle - std::unique_ptr box = aabb.getAABB(); + sf::FloatRect box = aabb.getAABB(); sf::Vector2f relpos = aabb.getPosition() - circle.getPosition(); sf::Vector2f closest = relpos; // on restreint la position relative pour rester // à l'intérieur du rectangle - if (closest.x < -box->width / 2) { - closest.x = -box->width / 2; + if (closest.x < -box.width / 2) { + closest.x = -box.width / 2; } - if (closest.x > box->width / 2) { - closest.x = box->width / 2; + if (closest.x > box.width / 2) { + closest.x = box.width / 2; } - if (closest.y < -box->height / 2) { - closest.y = -box->height / 2; + if (closest.y < -box.height / 2) { + closest.y = -box.height / 2; } - if (closest.y > box->height / 2) { - closest.y = box->height / 2; + if (closest.y > box.height / 2) { + closest.y = box.height / 2; } // si la position n'a pas été changée, elle était déjà @@ -50,15 +50,15 @@ bool circleToAABB(CollisionData& data) { // on se colle au bord le plus proche du rectangle if (std::abs(relpos.x) > std::abs(relpos.y)) { if (closest.x > 0) { - closest.x = box->width / 2; + closest.x = box.width / 2; } else { - closest.x = -box->width / 2; + closest.x = -box.width / 2; } } else { if (closest.y > 0) { - closest.y = box->height / 2; + closest.y = box.height / 2; } else { - closest.y = -box->height / 2; + closest.y = -box.height / 2; } } } @@ -144,12 +144,12 @@ bool AABBToAABB(CollisionData& data) { Object& aabb_a = data.obj_a; Object& aabb_b = data.obj_b; - std::unique_ptr box_a = aabb_a.getAABB(); - std::unique_ptr box_b = aabb_b.getAABB(); + sf::FloatRect box_a = aabb_a.getAABB(); + sf::FloatRect box_b = aabb_b.getAABB(); sf::Vector2f relpos = aabb_b.getPosition() - aabb_a.getPosition(); - float overlap_x = box_a->width / 2 + box_b->width / 2 - std::abs(relpos.x); - float overlap_y = box_a->height / 2 + box_b->height / 2 - std::abs(relpos.y); + float overlap_x = box_a.width / 2 + box_b.width / 2 - std::abs(relpos.x); + float overlap_y = box_a.height / 2 + box_b.height / 2 - std::abs(relpos.y); // si il n'y a pas de chauvauchement sur l'axe X et Y, pas de collision if (overlap_x <= 0 || overlap_y <= 0) { diff --git a/src/editor.cpp b/src/editor.cpp index a60bd44..bdd5973 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -248,7 +248,7 @@ ObjectPtr Editor::getObject(sf::Vector2f position) { std::vector& objects = getObjects(); for (unsigned int i = 0; i < objects.size(); i++) { - if (objects[i]->getAABB()->contains(position)) { + if (objects[i]->getAABB().contains(position)) { return objects[i]; } } @@ -274,7 +274,7 @@ ObjectPtr Editor::addObject(sf::Vector2f position) { float overlaps = false; for (unsigned int i = 0; i < objects.size(); i++) { - if (objects[i]->getAABB()->intersects(*object->getAABB())) { + if (objects[i]->getAABB().intersects(object->getAABB())) { overlaps = true; } } @@ -354,7 +354,7 @@ void Editor::select(sf::Vector2f top_left, sf::Vector2f bottom_right) { // sélection des éléments intersectant le rectangle for (unsigned int i = 0; i < objects.size(); i++) { - if (objects[i]->getAABB()->intersects(selection_rect)) { + if (objects[i]->getAABB().intersects(selection_rect)) { select(objects[i], SelectionMode::ADD); } } diff --git a/src/level.cpp b/src/level.cpp index e89eea8..21da421 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -30,12 +30,11 @@ std::map> object_type_map {GravityBlock::TYPE_ID, GravityBlock::load} }; -Level::Level(Manager& manager) : State(manager), camera_angle(180.f), - gravity_direction(GravityDirection::SOUTH) {} +Level::Level(Manager& manager) : State(manager) {} Level::~Level() {} void Level::load(std::string name) { - LevelReader file = getResourceManager().getLevelReader(name); + std::ifstream file = getResourceManager().getLevelReader(name); // vidage du niveau précédent et positionnement // de la caméra au centre du niveau @@ -44,7 +43,7 @@ void Level::load(std::string name) { // lecture de la signture du fichier ("BAR") char signature[3]; - file->read(signature, sizeof(signature)); + file.read(signature, sizeof(signature)); if (strncmp(signature, "BAR", sizeof(signature)) != 0) { throw std::runtime_error( @@ -54,7 +53,7 @@ void Level::load(std::string name) { // lecture de la version du fichier char file_version; - file->read(&file_version, 1); + file.read(&file_version, 1); if (file_version != 0) { throw std::runtime_error( @@ -64,23 +63,23 @@ void Level::load(std::string name) { // lecture du nom du niveau std::string std_name; - std::getline(*file, std_name, '\0'); + std::getline(file, std_name, '\0'); name = sf::String(std_name); // lecture du temps total du niveau - file->read(reinterpret_cast(&total_time), sizeof(total_time)); + file.read(reinterpret_cast(&total_time), sizeof(total_time)); total_time = ntohl(total_time); // lecture de la zone de jeu char control_points; - file->read(&control_points, 1); + file.read(&control_points, 1); zone.clear(); for (int i = 0; i < control_points; i++) { float pos_x, pos_y; - file->read(reinterpret_cast(&pos_x), sizeof(pos_x)); - file->read(reinterpret_cast(&pos_y), sizeof(pos_y)); + file.read(reinterpret_cast(&pos_x), sizeof(pos_x)); + file.read(reinterpret_cast(&pos_y), sizeof(pos_y)); pos_x *= Constants::GRID; pos_y *= Constants::GRID; @@ -91,19 +90,19 @@ void Level::load(std::string name) { // lecture des chemins de la musique et du fond std::string background_name; - std::getline(*file, music_name, '\0'); - std::getline(*file, background_name, '\0'); + std::getline(file, music_name, '\0'); + std::getline(file, background_name, '\0'); background.setTexture(getResourceManager().getTexture(background_name)); // lecture du nombre de blocs int block_count; - file->read(reinterpret_cast(&block_count), sizeof(block_count)); + file.read(reinterpret_cast(&block_count), sizeof(block_count)); block_count = ntohl(block_count); for (int i = 0; i < block_count; i++) { char block_type; - file->read(&block_type, 1); + file.read(&block_type, 1); // vérifie que le type est pris en charge // pour éviter une erreur de segmentation @@ -113,23 +112,23 @@ void Level::load(std::string name) { ); } - objects.push_back(object_type_map[block_type](*file)); + objects.push_back(object_type_map[block_type](file)); } - - file->close(); } void Level::save(std::string name) { - LevelWriter file = getResourceManager().getLevelWriter(name); + std::ofstream file = getResourceManager().getLevelWriter(name); // TODO: faire une fonction d'enregistrement - - file->close(); } void Level::begin() { + // TODO: ceci ne devrait pas être là + // (imaginons que l'on quitte et revienne à un niveau) camera = getWindow().getDefaultView(); camera.setCenter(0, 0); + camera_angle = 180.f; + gravity_direction = GravityDirection::SOUTH; if (music_name != "") { getResourceManager().playMusic(music_name); diff --git a/src/object.cpp b/src/object.cpp index 5545fe8..db09afa 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -147,7 +147,7 @@ bool Object::detectCollision(const Object& obj, CollisionData& data) const { // si les deux boîtes englobantes des deux objets ne // s'intersectent pas, il ne risque pas d'y avoir de collision - if (!getAABB()->intersects(*obj.getAABB())) { + if (!getAABB().intersects(obj.getAABB())) { return false; } diff --git a/src/player.cpp b/src/player.cpp index edda88a..6ea566e 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -9,8 +9,6 @@ const unsigned int Player::TYPE_ID = 1; Player::Player() : Object() { // déplacement de l'origine au centre de la balle sprite.setOrigin(sf::Vector2f(getRadius(), getRadius())); - sprite.setRadius(getRadius()); - sprite.setOutlineColor(sf::Color::Black); sprite.setOutlineThickness(1.5f); } @@ -65,21 +63,24 @@ sf::Vector2f Player::getForces(const Level& level) const { void Player::draw(Level& level) { // utilisation de la texture + sprite.setRadius(getRadius()); sprite.setTexture( &level.getResourceManager().getTexture("player.tga") ); // si le joueur est sélectionné, on met sa bordure en rouge - // if (isSelected()) { - // sprite.setColor(sf::Color(255, 0, 0)); - // } else { + if (isSelected()) { + sprite.setOutlineColor(sf::Color(255, 0, 0)); + } else { + sprite.setOutlineColor(sf::Color::Black); + // coloration du joueur en fonction de son numéro if (getPlayerNumber() == 0) { sprite.setFillColor(sf::Color(239, 83, 80)); } else if (getPlayerNumber() == 1) { sprite.setFillColor(sf::Color(92, 107, 192)); } - // } + } // déplacement du sprite à la position de la balle sprite.setPosition(getPosition()); @@ -100,12 +101,12 @@ void Player::updatePosition() { sprite.rotate((getPosition() - last_position).x * 3.f); } -std::unique_ptr Player::getAABB() const { - return std::unique_ptr(new sf::FloatRect( +sf::FloatRect Player::getAABB() const { + return sf::FloatRect( getPosition().x - getRadius(), getPosition().y - getRadius(), 2 * getRadius(), 2 * getRadius() - )); + ); } float Player::getRadius() const { diff --git a/src/resource_manager.cpp b/src/resource_manager.cpp index b405beb..6be7d01 100644 --- a/src/resource_manager.cpp +++ b/src/resource_manager.cpp @@ -38,50 +38,50 @@ ResourceManager::~ResourceManager() { sf::Texture& ResourceManager::getTexture(std::string name) { // si la texture est déjà chargée, on l'utilise directement if (textures.count(name) > 0) { - return textures[name]; + return *textures[name]; } - sf::Texture texture; + auto texture = std::unique_ptr(new sf::Texture); // tente de charger la texture dans le chemin "res/textures/name.png" - if (!texture.loadFromFile(resources_dir + SEP + "textures" + SEP + name)) { + if (!texture->loadFromFile(resources_dir + SEP + "textures" + SEP + name)) { throw std::runtime_error( "Impossible de charger l'image \"" + name + "\"" ); } - textures[name] = texture; - return textures[name]; + textures[name] = std::move(texture); + return *textures[name]; } sf::Font& ResourceManager::getFont(std::string name) { // si la police est déjà chargée, on l'utilise directement if (fonts.count(name) > 0) { - return fonts[name]; + return *fonts[name]; } - sf::Font font; + auto font = std::unique_ptr(new sf::Font); // tente de charger la police depuis le dossier "res/fonts" - if (!font.loadFromFile(resources_dir + SEP + "fonts" + SEP + name)) { + if (!font->loadFromFile(resources_dir + SEP + "fonts" + SEP + name)) { throw std::runtime_error( "Impossible de charger la police \"" + name + "\"" ); } - fonts[name] = font; - return fonts[name]; + fonts[name] = std::move(font); + return *fonts[name]; } -LevelReader ResourceManager::getLevelReader(std::string name) { - LevelReader reader = LevelReader(new std::ifstream); - reader->open( +std::ifstream ResourceManager::getLevelReader(std::string name) { + std::ifstream reader; + reader.open( resources_dir + SEP + "levels" + SEP + name, std::ios::binary | std::ios::in ); // on vérifie que le fichier ait correctement été ouvert en lecture - if (reader->fail()) { + if (reader.fail()) { throw std::runtime_error( "Impossible de charger le niveau \"" + name + "\" " + "(" + std::string(strerror(errno)) + ")" @@ -91,15 +91,15 @@ LevelReader ResourceManager::getLevelReader(std::string name) { return reader; } -LevelWriter ResourceManager::getLevelWriter(std::string name) { - LevelWriter writer = LevelWriter(new std::ofstream); - writer->open( +std::ofstream ResourceManager::getLevelWriter(std::string name) { + std::ofstream writer; + writer.open( resources_dir + SEP + "levels" + SEP + name, - std::ios::binary | std::ios::in + std::ios::binary | std::ios::out ); // on vérifie que le fichier ait correctement été ouvert en écriture - if (writer->fail()) { + if (writer.fail()) { throw std::runtime_error( "Impossible d'écrire le niveau '" + name + "' " + "(" + std::string(strerror(errno)) + ")"