Amélioration interface ResourceManager et réorganisation ressources
This commit is contained in:
parent
2b177950b4
commit
1bc28ad509
|
@ -59,14 +59,14 @@ public:
|
||||||
virtual ~Level();
|
virtual ~Level();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Charge un niveau de jeu depuis le fichier donné
|
* Charge un niveau de jeu avec le nom donné
|
||||||
*/
|
*/
|
||||||
virtual void load(std::ifstream& file);
|
virtual void load(std::string name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sauvegarde la configuration actuelle comme un niveau
|
* Sauvegarde la configuration actuelle dans le niveau donné
|
||||||
*/
|
*/
|
||||||
virtual void save();
|
virtual void save(std::string name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appelé par le manager lorsque l'état commence à être utilisé
|
* Appelé par le manager lorsque l'état commence à être utilisé
|
||||||
|
|
|
@ -3,13 +3,22 @@
|
||||||
|
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include <SFML/Audio.hpp>
|
#include <SFML/Audio.hpp>
|
||||||
#include <map>
|
#include <unordered_map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
typedef std::unique_ptr<std::ifstream> LevelReader;
|
||||||
|
typedef std::unique_ptr<std::ofstream> LevelWriter;
|
||||||
|
|
||||||
class ResourceManager {
|
class ResourceManager {
|
||||||
private:
|
private:
|
||||||
std::map<std::string, sf::Texture> textures;
|
std::string resources_dir;
|
||||||
std::map<std::string, sf::Font> fonts;
|
|
||||||
|
std::unordered_map<std::string, sf::Texture> textures;
|
||||||
|
std::unordered_map<std::string, sf::Font> fonts;
|
||||||
|
|
||||||
|
float music_volume;
|
||||||
sf::Music music;
|
sf::Music music;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -31,25 +40,36 @@ public:
|
||||||
sf::Font& getFont(std::string name);
|
sf::Font& getFont(std::string name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change la musique en lecture de fond
|
* Récupère un lecteur de fichier vers le niveau donné
|
||||||
* Doit être utilisé pour la lecture en continu
|
* (penser à refermer après usage)
|
||||||
*/
|
*/
|
||||||
void setMusic(std::string name);
|
LevelReader getLevelReader(std::string name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Démarre la musique de fond
|
* Récupère un jacob de fichier vers le niveau donné
|
||||||
|
* (penser à refermer après usage)
|
||||||
*/
|
*/
|
||||||
void playMusic();
|
LevelWriter getLevelWriter(std::string name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Met en pause la musique de fond
|
* Démarre la musique de fond donnée
|
||||||
*/
|
*/
|
||||||
void pauseMusic();
|
void playMusic(std::string name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Arrête la musique de fond
|
* Arrête la musique de fond
|
||||||
*/
|
*/
|
||||||
void stopMusic();
|
void stopMusic();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère le volume de la musique de fond
|
||||||
|
*/
|
||||||
|
float getMusicVolume();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifie le volume de la musique de fond
|
||||||
|
*/
|
||||||
|
void setMusicVolume(float set_music_volume);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 764 B After Width: | Height: | Size: 764 B |
|
@ -34,6 +34,8 @@ Editor::~Editor() {}
|
||||||
|
|
||||||
void Editor::begin() {
|
void Editor::begin() {
|
||||||
Level::begin();
|
Level::begin();
|
||||||
|
|
||||||
|
getResourceManager().playMusic("editor.ogg");
|
||||||
getWindow().setFramerateLimit(60);
|
getWindow().setFramerateLimit(60);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,18 +34,17 @@ Level::Level(Manager& manager) : State(manager), camera_angle(180.f),
|
||||||
gravity_direction(GravityDirection::SOUTH) {}
|
gravity_direction(GravityDirection::SOUTH) {}
|
||||||
Level::~Level() {}
|
Level::~Level() {}
|
||||||
|
|
||||||
void Level::load(std::ifstream& file) {
|
void Level::load(std::string name) {
|
||||||
// vide le niveau précédent s'il y a lieu
|
LevelReader file = getResourceManager().getLevelReader(name);
|
||||||
if (objects.size() != 0) {
|
|
||||||
objects.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// positionnement de la caméra au centre du niveau
|
// vidage du niveau précédent et positionnement
|
||||||
|
// de la caméra au centre du niveau
|
||||||
|
objects.clear();
|
||||||
camera.setCenter(0, 0);
|
camera.setCenter(0, 0);
|
||||||
|
|
||||||
// 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(
|
||||||
|
@ -55,7 +54,7 @@ void Level::load(std::ifstream& file) {
|
||||||
|
|
||||||
// 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(
|
||||||
|
@ -65,23 +64,23 @@ void Level::load(std::ifstream& file) {
|
||||||
|
|
||||||
// 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;
|
||||||
|
@ -92,19 +91,19 @@ void Level::load(std::ifstream& file) {
|
||||||
// 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
|
||||||
|
@ -114,25 +113,28 @@ void Level::load(std::ifstream& file) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
objects.push_back(object_type_map[block_type](file));
|
objects.push_back(object_type_map[block_type](*file));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Level::save() {
|
void Level::save(std::string name) {
|
||||||
|
LevelWriter file = getResourceManager().getLevelWriter(name);
|
||||||
|
|
||||||
// TODO: faire une fonction d'enregistrement
|
// TODO: faire une fonction d'enregistrement
|
||||||
|
|
||||||
|
file->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Level::begin() {
|
void Level::begin() {
|
||||||
ResourceManager& resources = getResourceManager();
|
|
||||||
|
|
||||||
camera = getWindow().getDefaultView();
|
camera = getWindow().getDefaultView();
|
||||||
camera.setCenter(0, 0);
|
camera.setCenter(0, 0);
|
||||||
|
|
||||||
if (music_name != "") {
|
if (music_name != "") {
|
||||||
resources.setMusic(music_name);
|
getResourceManager().playMusic(music_name);
|
||||||
resources.playMusic();
|
|
||||||
} else {
|
} else {
|
||||||
resources.stopMusic();
|
getResourceManager().stopMusic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
Manager::Manager() : window(
|
Manager::Manager() : window(
|
||||||
sf::VideoMode(704, 480), "Skizzle", sf::Style::Default,
|
sf::VideoMode(704, 480), "Skizzle", sf::Style::Default,
|
||||||
sf::ContextSettings(0, 0, 2)
|
sf::ContextSettings(0, 0, 4)
|
||||||
), default_view(window.getDefaultView()), title(sf::String(L"")),
|
), default_view(window.getDefaultView()), title(sf::String(L"")),
|
||||||
state(NULL), next_state(NULL), running(false) {}
|
state(NULL), next_state(NULL), running(false) {}
|
||||||
|
|
||||||
|
|
15
src/menu.cpp
15
src/menu.cpp
|
@ -9,12 +9,9 @@ Menu::Menu(Manager& manager) : State(manager) {}
|
||||||
Menu::~Menu() {}
|
Menu::~Menu() {}
|
||||||
|
|
||||||
void Menu::begin() {
|
void Menu::begin() {
|
||||||
ResourceManager& resources = getResourceManager();
|
|
||||||
|
|
||||||
loadMainMenu();
|
loadMainMenu();
|
||||||
resources.setMusic("menu.wav");
|
|
||||||
resources.playMusic();
|
|
||||||
|
|
||||||
|
getResourceManager().playMusic("menu.ogg");
|
||||||
getWindow().setFramerateLimit(60);
|
getWindow().setFramerateLimit(60);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +19,7 @@ void Menu::frame(const std::vector<sf::Event>& events) {
|
||||||
// traitement des événements
|
// traitement des événements
|
||||||
State::frame(events);
|
State::frame(events);
|
||||||
|
|
||||||
// titre de la fenêtitre
|
// titre de la fenêtre
|
||||||
getManager().setTitle("");
|
getManager().setTitle("");
|
||||||
|
|
||||||
// affichage du menu
|
// affichage du menu
|
||||||
|
@ -170,13 +167,7 @@ void Menu::launchEditor() {
|
||||||
|
|
||||||
void Menu::launchGame(std::string name) {
|
void Menu::launchGame(std::string name) {
|
||||||
std::shared_ptr<Game> game = std::shared_ptr<Game>(new Game(getManager()));
|
std::shared_ptr<Game> game = std::shared_ptr<Game>(new Game(getManager()));
|
||||||
std::string path = "./levels/" + name;
|
game->load(name);
|
||||||
|
|
||||||
std::ifstream file;
|
|
||||||
file.open(path, std::ios::binary | std::ios::in);
|
|
||||||
game->load(file);
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
getManager().setState(game);
|
getManager().setState(game);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,18 @@
|
||||||
#include "resource_manager.hpp"
|
#include "resource_manager.hpp"
|
||||||
#include "whereami.h"
|
#include "whereami.h"
|
||||||
#include <memory>
|
#include <cstring>
|
||||||
|
|
||||||
ResourceManager::ResourceManager() {
|
// définition du séparateur de fichiers en fonction
|
||||||
music.setLoop(true);
|
// du type de système
|
||||||
}
|
#ifdef _WIN32
|
||||||
|
const std::string SEP = "\\";
|
||||||
|
#else
|
||||||
|
const std::string SEP = "/";
|
||||||
|
#endif
|
||||||
|
|
||||||
ResourceManager::~ResourceManager() {
|
ResourceManager::ResourceManager() : music_volume(5) {
|
||||||
textures.clear();
|
// on récupère le chemin actuel de l'exécutable pour pouvoir accéder
|
||||||
}
|
// au dossier des ressources qui est situé dans le même dossier
|
||||||
|
|
||||||
/**
|
|
||||||
* Récupère le chemin actuel de l'exécutable sous la forme
|
|
||||||
* d'une chaîne de caractères grâce à la librairie whereami
|
|
||||||
*/
|
|
||||||
std::string getCurrentDirectory() {
|
|
||||||
int length = wai_getExecutablePath(NULL, 0, NULL), dirname_length;
|
int length = wai_getExecutablePath(NULL, 0, NULL), dirname_length;
|
||||||
std::unique_ptr<char[]> buffer = std::unique_ptr<char[]>(new char[length + 1]);
|
std::unique_ptr<char[]> buffer = std::unique_ptr<char[]>(new char[length + 1]);
|
||||||
wai_getExecutablePath(buffer.get(), length, &dirname_length);
|
wai_getExecutablePath(buffer.get(), length, &dirname_length);
|
||||||
|
@ -24,19 +22,17 @@ std::string getCurrentDirectory() {
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.get()[length] = '\0';
|
buffer.get()[length] = '\0';
|
||||||
return std::string(buffer.get()).substr(0, dirname_length);
|
std::string base_dir = std::string(buffer.get()).substr(0, dirname_length);
|
||||||
|
resources_dir = base_dir + SEP + "res" + SEP;
|
||||||
|
|
||||||
|
// initialisation de la musique en bouclage et au volume par défaut
|
||||||
|
music.setLoop(true);
|
||||||
|
music.setVolume(music_volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
ResourceManager::~ResourceManager() {
|
||||||
* Récupère le chemin absolu vers la ressource dont
|
textures.clear();
|
||||||
* le nom est passé en argument
|
fonts.clear();
|
||||||
*/
|
|
||||||
inline std::string getResourcePath(std::string name) {
|
|
||||||
#ifdef _WIN32
|
|
||||||
return getCurrentDirectory() + "\\res\\" + name;
|
|
||||||
#else
|
|
||||||
return getCurrentDirectory() + "/res/" + name;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sf::Texture& ResourceManager::getTexture(std::string name) {
|
sf::Texture& ResourceManager::getTexture(std::string name) {
|
||||||
|
@ -47,9 +43,11 @@ sf::Texture& ResourceManager::getTexture(std::string name) {
|
||||||
|
|
||||||
sf::Texture texture;
|
sf::Texture texture;
|
||||||
|
|
||||||
// tente de charger la texture dans le chemin "CWD/res/name"
|
// tente de charger la texture dans le chemin "res/textures/name.png"
|
||||||
if (!texture.loadFromFile(getResourcePath(name))) {
|
if (!texture.loadFromFile(resources_dir + SEP + "textures" + SEP + name)) {
|
||||||
throw std::runtime_error("Impossible de charger l'image : " + name);
|
throw std::runtime_error(
|
||||||
|
"Impossible de charger l'image \"" + name + "\""
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
textures[name] = texture;
|
textures[name] = texture;
|
||||||
|
@ -64,29 +62,71 @@ sf::Font& ResourceManager::getFont(std::string name) {
|
||||||
|
|
||||||
sf::Font font;
|
sf::Font font;
|
||||||
|
|
||||||
// tente de charger la police dans le chemin "CWD/res/name"
|
// tente de charger la police depuis le dossier "res/fonts"
|
||||||
if (!font.loadFromFile(getResourcePath(name))) {
|
if (!font.loadFromFile(resources_dir + SEP + "fonts" + SEP + name)) {
|
||||||
throw std::runtime_error("Impossible de charger la police : " + name);
|
throw std::runtime_error(
|
||||||
|
"Impossible de charger la police \"" + name + "\""
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fonts[name] = font;
|
fonts[name] = font;
|
||||||
return fonts[name];
|
return fonts[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::setMusic(std::string name) {
|
LevelReader ResourceManager::getLevelReader(std::string name) {
|
||||||
if (!music.openFromFile(getResourcePath(name))) {
|
LevelReader reader = LevelReader(new std::ifstream);
|
||||||
|
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()) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
"Impossible de charger le niveau \"" + name + "\" " +
|
||||||
|
"(" + std::string(strerror(errno)) + ")"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
LevelWriter ResourceManager::getLevelWriter(std::string name) {
|
||||||
|
LevelWriter writer = LevelWriter(new std::ofstream);
|
||||||
|
writer->open(
|
||||||
|
resources_dir + SEP + "levels" + SEP + name,
|
||||||
|
std::ios::binary | std::ios::in
|
||||||
|
);
|
||||||
|
|
||||||
|
// on vérifie que le fichier ait correctement été ouvert en écriture
|
||||||
|
if (writer->fail()) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
"Impossible d'écrire le niveau '" + name + "' " +
|
||||||
|
"(" + std::string(strerror(errno)) + ")"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceManager::playMusic(std::string name) {
|
||||||
|
// tente de charger la musique depuis le dossier "res/musics"
|
||||||
|
if (!music.openFromFile(resources_dir + SEP + "musics" + SEP + name)) {
|
||||||
throw std::runtime_error("Impossible de charger la musique : " + name);
|
throw std::runtime_error("Impossible de charger la musique : " + name);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void ResourceManager::playMusic() {
|
|
||||||
music.play();
|
music.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::pauseMusic() {
|
|
||||||
music.pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResourceManager::stopMusic() {
|
void ResourceManager::stopMusic() {
|
||||||
music.stop();
|
music.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float ResourceManager::getMusicVolume() {
|
||||||
|
return music_volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceManager::setMusicVolume(float set_music_volume) {
|
||||||
|
music_volume = set_music_volume;
|
||||||
|
music.setVolume(music_volume);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue