On apprend à se servir des pointeurs peut-être ?
This commit is contained in:
		
							parent
							
								
									d83fdb18fd
								
							
						
					
					
						commit
						61a0122a01
					
				|  | @ -28,7 +28,7 @@ public: | |||
|     /**
 | ||||
|      * Récupère la boîte englobante du bloc | ||||
|      */ | ||||
|     virtual std::unique_ptr<sf::FloatRect> getAABB() const; | ||||
|     virtual sf::FloatRect getAABB() const; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Récupère le rayon du bloc | ||||
|  |  | |||
|  | @ -56,7 +56,7 @@ public: | |||
|     /**
 | ||||
|      * Récupère la boîte englobante de l'objet | ||||
|      */ | ||||
|     virtual std::unique_ptr<sf::FloatRect> getAABB() const = 0; | ||||
|     virtual sf::FloatRect getAABB() const = 0; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Récupère le rayon de l'objet | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ public: | |||
|     /**
 | ||||
|      * Récupère la boîte englobante du joueur | ||||
|      */ | ||||
|     virtual std::unique_ptr<sf::FloatRect> getAABB() const; | ||||
|     virtual sf::FloatRect getAABB() const; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Récupère le rayon du joueur | ||||
|  |  | |||
|  | @ -8,15 +8,18 @@ | |||
| #include <fstream> | ||||
| #include <memory> | ||||
| 
 | ||||
| typedef std::unique_ptr<std::ifstream> LevelReader; | ||||
| typedef std::unique_ptr<std::ofstream> 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<std::string, sf::Texture> textures; | ||||
|     std::unordered_map<std::string, sf::Font> fonts; | ||||
|     std::unordered_map<std::string, std::unique_ptr<sf::Texture>> textures; | ||||
|     std::unordered_map<std::string, std::unique_ptr<sf::Font>> 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 | ||||
|  |  | |||
|  | @ -71,12 +71,12 @@ void Block::activated(Level& level, Object& object) { | |||
|     // aux activations
 | ||||
| } | ||||
| 
 | ||||
| std::unique_ptr<sf::FloatRect> Block::getAABB() const { | ||||
|     return std::unique_ptr<sf::FloatRect>(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 { | ||||
|  |  | |||
|  | @ -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<sf::FloatRect> 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<sf::FloatRect> box_a = aabb_a.getAABB(); | ||||
|     std::unique_ptr<sf::FloatRect> 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) { | ||||
|  |  | |||
|  | @ -248,7 +248,7 @@ ObjectPtr Editor::getObject(sf::Vector2f position) { | |||
|     std::vector<ObjectPtr>& 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); | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -30,12 +30,11 @@ std::map<unsigned int, std::function<ObjectPtr(std::ifstream&)>> 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<char*>(&total_time), sizeof(total_time)); | ||||
|     file.read(reinterpret_cast<char*>(&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<char*>(&pos_x), sizeof(pos_x)); | ||||
|         file->read(reinterpret_cast<char*>(&pos_y), sizeof(pos_y)); | ||||
|         file.read(reinterpret_cast<char*>(&pos_x), sizeof(pos_x)); | ||||
|         file.read(reinterpret_cast<char*>(&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<char*>(&block_count), sizeof(block_count)); | ||||
|     file.read(reinterpret_cast<char*>(&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); | ||||
|  |  | |||
|  | @ -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; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<sf::FloatRect> Player::getAABB() const { | ||||
|     return std::unique_ptr<sf::FloatRect>(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 { | ||||
|  |  | |||
|  | @ -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<sf::Texture>(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<sf::Font>(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)) + ")" | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue