Préchargement des ressources avant le démarrage du jeu pour
éviter l'erreur type "ne répond pas"
This commit is contained in:
parent
13fc2e3b92
commit
6eaa4fb77f
|
@ -32,8 +32,15 @@ endif()
|
||||||
# Recherche des librairies
|
# Recherche des librairies
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}" ${CMAKE_MODULE_PATH})
|
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}" ${CMAKE_MODULE_PATH})
|
||||||
add_executable(ptf ${SOURCES})
|
add_executable(ptf ${SOURCES})
|
||||||
|
|
||||||
find_package(SFML 2 REQUIRED system window graphics network audio)
|
find_package(SFML 2 REQUIRED system window graphics network audio)
|
||||||
|
find_package(Boost 1.60.0 COMPONENTS system filesystem)
|
||||||
|
|
||||||
|
include_directories(${SFML_INCLUDE_DIRS})
|
||||||
|
include_directories(${Boost_INCLUDE_DIRS})
|
||||||
|
|
||||||
target_link_libraries(ptf ${SFML_LIBRARIES})
|
target_link_libraries(ptf ${SFML_LIBRARIES})
|
||||||
|
target_link_libraries(ptf ${Boost_LIBRARIES})
|
||||||
|
|
||||||
# Installation de l'exécutable
|
# Installation de l'exécutable
|
||||||
install(TARGETS ptf DESTINATION bin)
|
install(TARGETS ptf DESTINATION bin)
|
||||||
|
|
|
@ -12,13 +12,12 @@
|
||||||
class Manager {
|
class Manager {
|
||||||
private:
|
private:
|
||||||
sf::RenderWindow window;
|
sf::RenderWindow window;
|
||||||
|
ResourceManager resource_manager;
|
||||||
|
|
||||||
sf::Clock clock;
|
sf::Clock clock;
|
||||||
sf::View default_view;
|
sf::View default_view;
|
||||||
sf::String title;
|
sf::String title;
|
||||||
|
|
||||||
ResourceManager resource_manager;
|
|
||||||
std::vector<sf::Event> events;
|
|
||||||
|
|
||||||
std::shared_ptr<State> state;
|
std::shared_ptr<State> state;
|
||||||
std::shared_ptr<State> next_state;
|
std::shared_ptr<State> next_state;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include <SFML/Audio.hpp>
|
#include <SFML/Audio.hpp>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -16,29 +17,34 @@
|
||||||
*/
|
*/
|
||||||
class ResourceManager {
|
class ResourceManager {
|
||||||
private:
|
private:
|
||||||
std::string resources_dir;
|
bool preloaded;
|
||||||
|
|
||||||
|
boost::filesystem::path textures_path;
|
||||||
std::unordered_map<std::string, std::unique_ptr<sf::Texture>> textures;
|
std::unordered_map<std::string, std::unique_ptr<sf::Texture>> textures;
|
||||||
|
boost::filesystem::path fonts_path;
|
||||||
std::unordered_map<std::string, std::unique_ptr<sf::Font>> fonts;
|
std::unordered_map<std::string, std::unique_ptr<sf::Font>> fonts;
|
||||||
|
|
||||||
|
boost::filesystem::path levels_path;
|
||||||
|
|
||||||
|
boost::filesystem::path musics_path;
|
||||||
float music_volume;
|
float music_volume;
|
||||||
sf::Music music;
|
sf::Music music;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ResourceManager();
|
ResourceManager();
|
||||||
~ResourceManager();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Récupère une image. Réutilise l'image déjà chargée
|
* Précharge toutes les ressources préchargeables
|
||||||
* si elle l'a déjà été, sinon, tente de la charger
|
*/
|
||||||
* depuis son emplacement
|
void preload();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère une texture préchargée
|
||||||
*/
|
*/
|
||||||
sf::Texture& getTexture(std::string name);
|
sf::Texture& getTexture(std::string name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Récupère la police demandée. Réutilise une police
|
* Récupère une police préchargée
|
||||||
* déjà chargée si elle a déjà été demandée, sinon, la
|
|
||||||
* charge depuis son emplacement
|
|
||||||
*/
|
*/
|
||||||
sf::Font& getFont(std::string name);
|
sf::Font& getFont(std::string name);
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,9 @@ Editor::~Editor() {}
|
||||||
void Editor::begin() {
|
void Editor::begin() {
|
||||||
Level::begin();
|
Level::begin();
|
||||||
|
|
||||||
|
getResourceManager().stopMusic();
|
||||||
|
// TODO: on doit arrêter la musique car celle du
|
||||||
|
// niveau est chargée par dessous dans level.. C'est sale
|
||||||
getResourceManager().playMusic("editor.ogg");
|
getResourceManager().playMusic("editor.ogg");
|
||||||
getWindow().setFramerateLimit(Manager::FPS);
|
getWindow().setFramerateLimit(Manager::FPS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,21 @@
|
||||||
|
#include <iostream>
|
||||||
#include "manager.hpp"
|
#include "manager.hpp"
|
||||||
|
|
||||||
const unsigned int Manager::FPS = 60;
|
const unsigned int Manager::FPS = 60;
|
||||||
const sf::Time Manager::FRAME_TIME = sf::seconds(1.f / Manager::FPS);
|
const sf::Time Manager::FRAME_TIME = sf::seconds(1.f / Manager::FPS);
|
||||||
|
|
||||||
Manager::Manager() : window(
|
Manager::Manager() : default_view(window.getDefaultView()),
|
||||||
sf::VideoMode(704, 480), "Skizzle", sf::Style::Default,
|
title(sf::String(L"")), state(NULL), next_state(NULL), running(false) {
|
||||||
sf::ContextSettings(0, 0, 2)
|
// préchargement des textures
|
||||||
), default_view(window.getDefaultView()), title(sf::String(L"")),
|
resource_manager.preload();
|
||||||
state(NULL), next_state(NULL), running(false) {}
|
|
||||||
|
// création de la fenêtre (après avoir préchargé les ressources,
|
||||||
|
// on évite ainsi tout lag pendant le traitement des événements)
|
||||||
|
window.create(
|
||||||
|
sf::VideoMode(704, 480), "Skizzle", sf::Style::Default,
|
||||||
|
sf::ContextSettings(0, 0, 2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void Manager::start() {
|
void Manager::start() {
|
||||||
running = true;
|
running = true;
|
||||||
|
|
|
@ -1,86 +1,104 @@
|
||||||
#include "resource_manager.hpp"
|
#include "resource_manager.hpp"
|
||||||
#include "whereami.h"
|
#include <iostream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
// définition du séparateur de fichiers en fonction
|
using dir_iter = boost::filesystem::directory_iterator;
|
||||||
// du type de système
|
using fs_path = boost::filesystem::path;
|
||||||
#ifdef _WIN32
|
|
||||||
const std::string SEP = "\\";
|
|
||||||
#else
|
|
||||||
const std::string SEP = "/";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ResourceManager::ResourceManager() : music_volume(5) {
|
|
||||||
// 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
|
|
||||||
int length = wai_getExecutablePath(NULL, 0, NULL), dirname_length;
|
|
||||||
std::unique_ptr<char[]> buffer = std::unique_ptr<char[]>(new char[length + 1]);
|
|
||||||
wai_getExecutablePath(buffer.get(), length, &dirname_length);
|
|
||||||
|
|
||||||
if (length == 0) {
|
|
||||||
throw std::runtime_error("Impossible de déterminer le chemin actuel");
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer.get()[length] = '\0';
|
|
||||||
std::string base_dir = std::string(buffer.get()).substr(0, dirname_length);
|
|
||||||
resources_dir = base_dir + SEP + "res" + SEP;
|
|
||||||
|
|
||||||
|
ResourceManager::ResourceManager() : preloaded(false), music_volume(20) {
|
||||||
// initialisation de la musique en bouclage et au volume par défaut
|
// initialisation de la musique en bouclage et au volume par défaut
|
||||||
music.setLoop(true);
|
music.setLoop(true);
|
||||||
music.setVolume(music_volume);
|
music.setVolume(music_volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceManager::~ResourceManager() {
|
void ResourceManager::preload() {
|
||||||
textures.clear();
|
if (preloaded) {
|
||||||
fonts.clear();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs_path current = boost::filesystem::current_path();
|
||||||
|
dir_iter end;
|
||||||
|
|
||||||
|
// on garde une référence aux chemins des différentes ressources
|
||||||
|
textures_path = current / "res/textures";
|
||||||
|
fonts_path = current / "res/fonts";
|
||||||
|
levels_path = current / "res/levels";
|
||||||
|
musics_path = current / "res/musics";
|
||||||
|
|
||||||
|
// préchargement de toutes les textures
|
||||||
|
for (dir_iter it(textures_path); it != end; ++it) {
|
||||||
|
if (boost::filesystem::is_regular_file(it->path())) {
|
||||||
|
std::string full_path = boost::filesystem::canonical(it->path()).string();
|
||||||
|
std::string name = it->path().filename().string();
|
||||||
|
|
||||||
|
auto texture = std::unique_ptr<sf::Texture>(new sf::Texture);
|
||||||
|
std::cout << "Chargement de la texture " << name << "... ";
|
||||||
|
|
||||||
|
if (!texture->loadFromFile(full_path)) {
|
||||||
|
std::cerr << "ERREUR!" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "OK!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
textures[name] = std::move(texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// préchargement de toutes les polices
|
||||||
|
for (dir_iter it(fonts_path); it != end; ++it) {
|
||||||
|
if (boost::filesystem::is_regular_file(it->path())) {
|
||||||
|
std::string full_path = boost::filesystem::canonical(it->path()).string();
|
||||||
|
std::string name = it->path().filename().string();
|
||||||
|
|
||||||
|
auto font = std::unique_ptr<sf::Font>(new sf::Font);
|
||||||
|
std::cout << "Chargement de la police " << name << "... ";
|
||||||
|
|
||||||
|
if (!font->loadFromFile(full_path)) {
|
||||||
|
std::cerr << "ERREUR!" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "OK!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
fonts[name] = std::move(font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
preloaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
if (textures.count(name) == 0) {
|
||||||
if (textures.count(name) > 0) {
|
|
||||||
return *textures[name];
|
|
||||||
}
|
|
||||||
|
|
||||||
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)) {
|
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"Impossible de charger l'image \"" + name + "\""
|
"Impossible de charger la texture inexistante : " + name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
if (fonts.count(name) == 0) {
|
||||||
if (fonts.count(name) > 0) {
|
|
||||||
return *fonts[name];
|
|
||||||
}
|
|
||||||
|
|
||||||
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)) {
|
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"Impossible de charger la police \"" + name + "\""
|
"Impossible de charger la police inexistante : " + name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fonts[name] = std::move(font);
|
|
||||||
return *fonts[name];
|
return *fonts[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ResourceManager::getLevelPath(std::string name) {
|
std::string ResourceManager::getLevelPath(std::string name) {
|
||||||
return resources_dir + SEP + "levels" + SEP + name;
|
return boost::filesystem::canonical(levels_path / name).string();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::playMusic(std::string name) {
|
void ResourceManager::playMusic(std::string name) {
|
||||||
// tente de charger la musique depuis le dossier "res/musics"
|
// tente de charger la musique depuis le dossier "res/musics"
|
||||||
if (!music.openFromFile(resources_dir + SEP + "musics" + SEP + name)) {
|
std::string full_path = boost::filesystem::canonical(musics_path / name).string();
|
||||||
throw std::runtime_error("Impossible de charger la musique : " + name);
|
std::cout << "Lecture de la musique " << name << "... ";
|
||||||
|
|
||||||
|
if (!music.openFromFile(full_path)) {
|
||||||
|
std::cerr << "ERREUR!" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "OK!" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
music.play();
|
music.play();
|
||||||
|
|
Loading…
Reference in New Issue