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
*/
virtual std::unique_ptr<sf::FloatRect> getAABB() const;
virtual sf::FloatRect getAABB() const;
/**
* Récupère le rayon du bloc

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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);

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
// s'intersectent pas, il ne risque pas d'y avoir de collision
if (!getAABB()->intersects(*obj.getAABB())) {
if (!getAABB().intersects(obj.getAABB())) {
return false;
}

View File

@ -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 {

View File

@ -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)) + ")"