On apprend à se servir des pointeurs peut-être ?

This commit is contained in:
Mattéo Delabre 2016-04-10 05:10:27 +02:00
parent d83fdb18fd
commit 61a0122a01
11 changed files with 85 additions and 84 deletions

View File

@ -28,7 +28,7 @@ public:
/** /**
* Récupère la boîte englobante du bloc * 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 * Récupère le rayon du bloc

View File

@ -56,7 +56,7 @@ public:
/** /**
* Récupère la boîte englobante de l'objet * 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 * Récupère le rayon de l'objet

View File

@ -32,7 +32,7 @@ public:
/** /**
* Récupère la boîte englobante du joueur * 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 * Récupère le rayon du joueur

View File

@ -8,15 +8,18 @@
#include <fstream> #include <fstream>
#include <memory> #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 { class ResourceManager {
private: private:
std::string resources_dir; std::string resources_dir;
std::unordered_map<std::string, sf::Texture> textures; std::unordered_map<std::string, std::unique_ptr<sf::Texture>> textures;
std::unordered_map<std::string, sf::Font> fonts; std::unordered_map<std::string, std::unique_ptr<sf::Font>> fonts;
float music_volume; float music_volume;
sf::Music music; sf::Music music;
@ -41,15 +44,13 @@ public:
/** /**
* Récupère un lecteur de fichier vers le niveau donné * 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é * 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 * Démarre la musique de fond donnée

View File

@ -71,12 +71,12 @@ void Block::activated(Level& level, Object& object) {
// aux activations // aux activations
} }
std::unique_ptr<sf::FloatRect> Block::getAABB() const { sf::FloatRect Block::getAABB() const {
return std::unique_ptr<sf::FloatRect>(new sf::FloatRect( return sf::FloatRect(
getPosition().x - Constants::GRID / 2, getPosition().x - Constants::GRID / 2,
getPosition().y - Constants::GRID / 2, getPosition().y - Constants::GRID / 2,
Constants::GRID, Constants::GRID Constants::GRID, Constants::GRID
)); );
} }
float Block::getRadius() const { float Block::getRadius() const {

View File

@ -18,26 +18,26 @@ bool circleToAABB(CollisionData& data) {
// recherche du point le plus proche du centre du cercle // recherche du point le plus proche du centre du cercle
// sur le rectangle. On regarde la position relative du cercle // sur le rectangle. On regarde la position relative du cercle
// par rapport au rectangle // 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 relpos = aabb.getPosition() - circle.getPosition();
sf::Vector2f closest = relpos; sf::Vector2f closest = relpos;
// on restreint la position relative pour rester // on restreint la position relative pour rester
// à l'intérieur du rectangle // à l'intérieur du rectangle
if (closest.x < -box->width / 2) { if (closest.x < -box.width / 2) {
closest.x = -box->width / 2; closest.x = -box.width / 2;
} }
if (closest.x > box->width / 2) { if (closest.x > box.width / 2) {
closest.x = box->width / 2; closest.x = box.width / 2;
} }
if (closest.y < -box->height / 2) { if (closest.y < -box.height / 2) {
closest.y = -box->height / 2; closest.y = -box.height / 2;
} }
if (closest.y > box->height / 2) { if (closest.y > box.height / 2) {
closest.y = box->height / 2; closest.y = box.height / 2;
} }
// si la position n'a pas été changée, elle était déjà // 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 // on se colle au bord le plus proche du rectangle
if (std::abs(relpos.x) > std::abs(relpos.y)) { if (std::abs(relpos.x) > std::abs(relpos.y)) {
if (closest.x > 0) { if (closest.x > 0) {
closest.x = box->width / 2; closest.x = box.width / 2;
} else { } else {
closest.x = -box->width / 2; closest.x = -box.width / 2;
} }
} else { } else {
if (closest.y > 0) { if (closest.y > 0) {
closest.y = box->height / 2; closest.y = box.height / 2;
} else { } 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_a = data.obj_a;
Object& aabb_b = data.obj_b; Object& aabb_b = data.obj_b;
std::unique_ptr<sf::FloatRect> box_a = aabb_a.getAABB(); sf::FloatRect box_a = aabb_a.getAABB();
std::unique_ptr<sf::FloatRect> box_b = aabb_b.getAABB(); sf::FloatRect box_b = aabb_b.getAABB();
sf::Vector2f relpos = aabb_b.getPosition() - aabb_a.getPosition(); 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_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_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 // si il n'y a pas de chauvauchement sur l'axe X et Y, pas de collision
if (overlap_x <= 0 || overlap_y <= 0) { if (overlap_x <= 0 || overlap_y <= 0) {

View File

@ -248,7 +248,7 @@ ObjectPtr Editor::getObject(sf::Vector2f position) {
std::vector<ObjectPtr>& objects = getObjects(); std::vector<ObjectPtr>& objects = getObjects();
for (unsigned int i = 0; i < objects.size(); i++) { for (unsigned int i = 0; i < objects.size(); i++) {
if (objects[i]->getAABB()->contains(position)) { if (objects[i]->getAABB().contains(position)) {
return objects[i]; return objects[i];
} }
} }
@ -274,7 +274,7 @@ ObjectPtr Editor::addObject(sf::Vector2f position) {
float overlaps = false; float overlaps = false;
for (unsigned int i = 0; i < objects.size(); i++) { 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; 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 // sélection des éléments intersectant le rectangle
for (unsigned int i = 0; i < objects.size(); i++) { 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); select(objects[i], SelectionMode::ADD);
} }
} }

View File

@ -30,12 +30,11 @@ std::map<unsigned int, std::function<ObjectPtr(std::ifstream&)>> object_type_map
{GravityBlock::TYPE_ID, GravityBlock::load} {GravityBlock::TYPE_ID, GravityBlock::load}
}; };
Level::Level(Manager& manager) : State(manager), camera_angle(180.f), Level::Level(Manager& manager) : State(manager) {}
gravity_direction(GravityDirection::SOUTH) {}
Level::~Level() {} Level::~Level() {}
void Level::load(std::string name) { 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 // vidage du niveau précédent et positionnement
// de la caméra au centre du niveau // 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") // lecture de la signture du fichier ("BAR")
char signature[3]; char signature[3];
file->read(signature, sizeof(signature)); file.read(signature, sizeof(signature));
if (strncmp(signature, "BAR", sizeof(signature)) != 0) { if (strncmp(signature, "BAR", sizeof(signature)) != 0) {
throw std::runtime_error( throw std::runtime_error(
@ -54,7 +53,7 @@ void Level::load(std::string name) {
// lecture de la version du fichier // lecture de la version du fichier
char file_version; char file_version;
file->read(&file_version, 1); file.read(&file_version, 1);
if (file_version != 0) { if (file_version != 0) {
throw std::runtime_error( throw std::runtime_error(
@ -64,23 +63,23 @@ void Level::load(std::string name) {
// lecture du nom du niveau // lecture du nom du niveau
std::string std_name; std::string std_name;
std::getline(*file, std_name, '\0'); std::getline(file, std_name, '\0');
name = sf::String(std_name); name = sf::String(std_name);
// lecture du temps total du niveau // 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); total_time = ntohl(total_time);
// lecture de la zone de jeu // lecture de la zone de jeu
char control_points; char control_points;
file->read(&control_points, 1); file.read(&control_points, 1);
zone.clear(); zone.clear();
for (int i = 0; i < control_points; i++) { for (int i = 0; i < control_points; i++) {
float pos_x, pos_y; float pos_x, pos_y;
file->read(reinterpret_cast<char*>(&pos_x), sizeof(pos_x)); 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_y), sizeof(pos_y));
pos_x *= Constants::GRID; pos_x *= Constants::GRID;
pos_y *= 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 // lecture des chemins de la musique et du fond
std::string background_name; std::string background_name;
std::getline(*file, music_name, '\0'); std::getline(file, music_name, '\0');
std::getline(*file, background_name, '\0'); std::getline(file, background_name, '\0');
background.setTexture(getResourceManager().getTexture(background_name)); background.setTexture(getResourceManager().getTexture(background_name));
// lecture du nombre de blocs // lecture du nombre de blocs
int block_count; 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); block_count = ntohl(block_count);
for (int i = 0; i < block_count; i++) { for (int i = 0; i < block_count; i++) {
char block_type; char block_type;
file->read(&block_type, 1); file.read(&block_type, 1);
// vérifie que le type est pris en charge // vérifie que le type est pris en charge
// pour éviter une erreur de segmentation // 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) { void Level::save(std::string name) {
LevelWriter file = getResourceManager().getLevelWriter(name); std::ofstream file = getResourceManager().getLevelWriter(name);
// TODO: faire une fonction d'enregistrement // TODO: faire une fonction d'enregistrement
file->close();
} }
void Level::begin() { void Level::begin() {
// TODO: ceci ne devrait pas être là
// (imaginons que l'on quitte et revienne à un niveau)
camera = getWindow().getDefaultView(); camera = getWindow().getDefaultView();
camera.setCenter(0, 0); camera.setCenter(0, 0);
camera_angle = 180.f;
gravity_direction = GravityDirection::SOUTH;
if (music_name != "") { if (music_name != "") {
getResourceManager().playMusic(music_name); getResourceManager().playMusic(music_name);

View File

@ -147,7 +147,7 @@ bool Object::detectCollision(const Object& obj, CollisionData& data) const {
// si les deux boîtes englobantes des deux objets ne // si les deux boîtes englobantes des deux objets ne
// s'intersectent pas, il ne risque pas d'y avoir de collision // s'intersectent pas, il ne risque pas d'y avoir de collision
if (!getAABB()->intersects(*obj.getAABB())) { if (!getAABB().intersects(obj.getAABB())) {
return false; return false;
} }

View File

@ -9,8 +9,6 @@ const unsigned int Player::TYPE_ID = 1;
Player::Player() : Object() { Player::Player() : Object() {
// déplacement de l'origine au centre de la balle // déplacement de l'origine au centre de la balle
sprite.setOrigin(sf::Vector2f(getRadius(), getRadius())); sprite.setOrigin(sf::Vector2f(getRadius(), getRadius()));
sprite.setRadius(getRadius());
sprite.setOutlineColor(sf::Color::Black);
sprite.setOutlineThickness(1.5f); sprite.setOutlineThickness(1.5f);
} }
@ -65,21 +63,24 @@ sf::Vector2f Player::getForces(const Level& level) const {
void Player::draw(Level& level) { void Player::draw(Level& level) {
// utilisation de la texture // utilisation de la texture
sprite.setRadius(getRadius());
sprite.setTexture( sprite.setTexture(
&level.getResourceManager().getTexture("player.tga") &level.getResourceManager().getTexture("player.tga")
); );
// si le joueur est sélectionné, on met sa bordure en rouge // si le joueur est sélectionné, on met sa bordure en rouge
// if (isSelected()) { if (isSelected()) {
// sprite.setColor(sf::Color(255, 0, 0)); sprite.setOutlineColor(sf::Color(255, 0, 0));
// } else { } else {
sprite.setOutlineColor(sf::Color::Black);
// coloration du joueur en fonction de son numéro // coloration du joueur en fonction de son numéro
if (getPlayerNumber() == 0) { if (getPlayerNumber() == 0) {
sprite.setFillColor(sf::Color(239, 83, 80)); sprite.setFillColor(sf::Color(239, 83, 80));
} else if (getPlayerNumber() == 1) { } else if (getPlayerNumber() == 1) {
sprite.setFillColor(sf::Color(92, 107, 192)); sprite.setFillColor(sf::Color(92, 107, 192));
} }
// } }
// déplacement du sprite à la position de la balle // déplacement du sprite à la position de la balle
sprite.setPosition(getPosition()); sprite.setPosition(getPosition());
@ -100,12 +101,12 @@ void Player::updatePosition() {
sprite.rotate((getPosition() - last_position).x * 3.f); sprite.rotate((getPosition() - last_position).x * 3.f);
} }
std::unique_ptr<sf::FloatRect> Player::getAABB() const { sf::FloatRect Player::getAABB() const {
return std::unique_ptr<sf::FloatRect>(new sf::FloatRect( return sf::FloatRect(
getPosition().x - getRadius(), getPosition().x - getRadius(),
getPosition().y - getRadius(), getPosition().y - getRadius(),
2 * getRadius(), 2 * getRadius() 2 * getRadius(), 2 * getRadius()
)); );
} }
float Player::getRadius() const { float Player::getRadius() const {

View File

@ -38,50 +38,50 @@ ResourceManager::~ResourceManager() {
sf::Texture& ResourceManager::getTexture(std::string name) { sf::Texture& ResourceManager::getTexture(std::string name) {
// si la texture est déjà chargée, on l'utilise directement // si la texture est déjà chargée, on l'utilise directement
if (textures.count(name) > 0) { 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" // 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( throw std::runtime_error(
"Impossible de charger l'image \"" + name + "\"" "Impossible de charger l'image \"" + name + "\""
); );
} }
textures[name] = texture; textures[name] = std::move(texture);
return textures[name]; return *textures[name];
} }
sf::Font& ResourceManager::getFont(std::string name) { sf::Font& ResourceManager::getFont(std::string name) {
// si la police est déjà chargée, on l'utilise directement // si la police est déjà chargée, on l'utilise directement
if (fonts.count(name) > 0) { 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" // 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( throw std::runtime_error(
"Impossible de charger la police \"" + name + "\"" "Impossible de charger la police \"" + name + "\""
); );
} }
fonts[name] = font; fonts[name] = std::move(font);
return fonts[name]; return *fonts[name];
} }
LevelReader ResourceManager::getLevelReader(std::string name) { std::ifstream ResourceManager::getLevelReader(std::string name) {
LevelReader reader = LevelReader(new std::ifstream); std::ifstream reader;
reader->open( reader.open(
resources_dir + SEP + "levels" + SEP + name, resources_dir + SEP + "levels" + SEP + name,
std::ios::binary | std::ios::in std::ios::binary | std::ios::in
); );
// on vérifie que le fichier ait correctement été ouvert en lecture // on vérifie que le fichier ait correctement été ouvert en lecture
if (reader->fail()) { if (reader.fail()) {
throw std::runtime_error( throw std::runtime_error(
"Impossible de charger le niveau \"" + name + "\" " + "Impossible de charger le niveau \"" + name + "\" " +
"(" + std::string(strerror(errno)) + ")" "(" + std::string(strerror(errno)) + ")"
@ -91,15 +91,15 @@ LevelReader ResourceManager::getLevelReader(std::string name) {
return reader; return reader;
} }
LevelWriter ResourceManager::getLevelWriter(std::string name) { std::ofstream ResourceManager::getLevelWriter(std::string name) {
LevelWriter writer = LevelWriter(new std::ofstream); std::ofstream writer;
writer->open( writer.open(
resources_dir + SEP + "levels" + SEP + name, 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 // on vérifie que le fichier ait correctement été ouvert en écriture
if (writer->fail()) { if (writer.fail()) {
throw std::runtime_error( throw std::runtime_error(
"Impossible d'écrire le niveau '" + name + "' " + "Impossible d'écrire le niveau '" + name + "' " +
"(" + std::string(strerror(errno)) + ")" "(" + std::string(strerror(errno)) + ")"