Chargement de niveaux

This commit is contained in:
Mattéo Delabre 2016-03-30 14:03:52 +02:00
parent de3d4f6311
commit fe7fa5c9a4
4 changed files with 101 additions and 42 deletions

View File

@ -2,6 +2,8 @@
#define __PTF_GAME_HPP__ #define __PTF_GAME_HPP__
#include <SFML/Audio.hpp> #include <SFML/Audio.hpp>
#include <fstream>
#include <vector>
#include "view.hpp" #include "view.hpp"
#include "object.hpp" #include "object.hpp"
#include "manager.hpp" #include "manager.hpp"
@ -13,31 +15,37 @@
*/ */
class Game : public View { class Game : public View {
private: private:
sf::View view; std::string level_name;
std::string music_path;
std::string background_path;
sf::Sprite sprite;
sf::Music music; sf::Music music;
float accumulator; float accumulator;
std::vector<Object*> objects;
std::vector<ObjectPtr> objects;
std::vector<std::pair<float, float>> level_zone;
/** /**
* Met à jour les objets du jeu pour * Met à jour les objets du jeu pour
* qu'ils s'adaptent au nouvel état * qu'ils s'adaptent au nouvel état
*/ */
void update(const Manager& manager); void update();
/** /**
* Dessine la scène du jeu couche par couche * Dessine la scène du jeu couche par couche
*/ */
void draw(Manager& manager); void draw();
public: public:
Game(); Game(Manager& manager);
virtual ~Game(); virtual ~Game();
/** /**
* Charge un niveau de jeu depuis le fichier donné * Charge un niveau de jeu depuis le fichier donné
*/ */
void load(); void load(std::ifstream& file);
/** /**
* Sauvegarde la configuration actuelle comme un niveau * Sauvegarde la configuration actuelle comme un niveau
@ -53,12 +61,7 @@ public:
* Demande le passage à la frame suivante sur * Demande le passage à la frame suivante sur
* cette vue * cette vue
*/ */
void frame(Manager& manager); void frame();
/**
* Ajoute un nouvel objet à la liste des objets du jeu
*/
void addObject(Object& object);
}; };
#endif #endif

BIN
levels/level1.dat Normal file

Binary file not shown.

View File

@ -1,34 +1,87 @@
#include "game.hpp" #include "game.hpp"
#include "constants.hpp" #include "constants.hpp"
#include "player.hpp" #include "player.hpp"
#include <cmath> #include <cstring>
#include <queue> #include <queue>
#include <utility>
#include <iostream>
Game::Game() : accumulator(0.f) { Game::Game(Manager& manager) : View(manager), accumulator(0.f) {}
if (!music.openFromFile("./res/music_lvl1.wav")) {
// erreur
}
music.play();
music.setVolume(15);
music.setLoop(true);
load();
}
Game::~Game() { Game::~Game() {
clear(); clear();
} }
void Game::load() { void Game::load(std::ifstream& file) {
// vide le niveau précédent s'il y a lieu // vide le niveau précédent s'il y a lieu
if (objects.size()) { if (objects.size()) {
clear(); clear();
} }
// TODO: faire une vraie fonction de chargement // lecture de la signture du fichier ("BAR")
Player* player1 = new Player(3.5f * Constants::GRID, 10 * Constants::GRID); char signature[3];
objects.push_back(player1); file.read(signature, sizeof(signature));
if (strncmp(signature, "BAR", 3) != 0) {
throw std::runtime_error(
"Impossible de lire le fichier : en-tête invalide"
);
}
// lecture de la version du fichier
char file_version;
file.read(&file_version, 1);
if (file_version != 0) {
throw std::runtime_error(
"Impossible de lire le fichier : version non prise en charge"
);
}
// lecture du nom du niveau
std::getline(file, level_name, '\0');
// lecture des positions initiales
char player_amount;
file.read(&player_amount, 1);
for (int i = 0; i < player_amount; i++) {
float pos_x, pos_y;
file.read((char*) &pos_x, sizeof(pos_x));
file.read((char*) &pos_y, sizeof(pos_y));
pos_x *= Constants::GRID;
pos_y *= Constants::GRID;
std::shared_ptr<Player> player = std::make_shared<Player>(pos_x, pos_y);
player->setPlayerNumber(i);
objects.push_back(std::dynamic_pointer_cast<Object>(player));
}
// lecture de la zone de vie
char control_points;
file.read(&control_points, 1);
level_zone.clear();
for (int i = 0; i < control_points; i++) {
float pos_x, pos_y;
file.read((char*) &pos_x, sizeof(pos_x));
file.read((char*) &pos_y, sizeof(pos_y));
pos_x *= Constants::GRID;
pos_y *= Constants::GRID;
level_zone.push_back(std::make_pair(pos_x, pos_y));
}
// lecture des chemins de la musique et du fond
std::getline(file, music_path, '\0');
std::getline(file, background_path, '\0');
manager.getResourceManager().setMusic(music_path);
manager.getResourceManager().playMusic();
} }
void Game::save() { void Game::save() {
@ -37,35 +90,31 @@ void Game::save() {
} }
void Game::clear() { void Game::clear() {
for (unsigned int i = 0; i < objects.size(); i++) {
delete objects[i];
}
objects.clear(); objects.clear();
} }
void Game::frame(Manager& manager) { void Game::frame() {
accumulator += manager.getElapsedTime(); accumulator += manager.getElapsedTime();
// tant qu'il reste du temps à passer, // tant qu'il reste du temps à passer,
// effectuer la simulation physique étape par étape // effectuer la simulation physique étape par étape
while (accumulator >= Constants::PHYSICS_TIME) { while (accumulator >= Constants::PHYSICS_TIME) {
accumulator -= Constants::PHYSICS_TIME; accumulator -= Constants::PHYSICS_TIME;
update(manager); update();
} }
draw(manager); draw();
} }
void Game::update(const Manager& manager) { void Game::update() {
std::vector<CollisionData> colliding; std::vector<CollisionData> colliding;
// détection des objets en collision // détection des objets en collision
for (unsigned int i = 0; i < objects.size(); i++) { for (unsigned int i = 0; i < objects.size(); i++) {
Object* objA = objects[i]; ObjectPtr objA = objects[i];
for (unsigned int j = i + 1; j < objects.size(); j++) { for (unsigned int j = i + 1; j < objects.size(); j++) {
Object* objB = objects[j]; ObjectPtr objB = objects[j];
CollisionData data(*objA, *objB); CollisionData data(*objA, *objB);
if (objA->detectCollision(*objB, data)) { if (objA->detectCollision(*objB, data)) {
@ -104,12 +153,12 @@ void Game::update(const Manager& manager) {
} }
} }
void Game::draw(Manager& manager) { void Game::draw() {
// efface la scène précédente et dessine la couche de fond // efface la scène précédente et dessine la couche de fond
manager.getWindow().clear(sf::Color(66, 165, 245)); manager.getWindow().clear(sf::Color(66, 165, 245));
// chargement de la file d'affichage des objets // chargement de la file d'affichage des objets
std::priority_queue<Object*, std::vector<Object*>, ObjectCompare> display_queue; std::priority_queue<ObjectPtr, std::vector<ObjectPtr>, ObjectCompare> display_queue;
for (unsigned int i = 0; i < objects.size(); i++) { for (unsigned int i = 0; i < objects.size(); i++) {
display_queue.push(objects[i]); display_queue.push(objects[i]);

View File

@ -6,10 +6,17 @@
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
#include <memory> #include <memory>
#include <fstream>
int main() { int main() {
Manager manager; Manager manager;
std::shared_ptr<Game> game = std::shared_ptr<Game>(new Game); std::shared_ptr<Game> game = std::make_shared<Game>(manager);
// ouverture du niveau
std::ifstream file;
file.open("./levels/level1.dat", std::ios::binary | std::ios::in);
game->load(file);
file.close();
manager.setView(game); manager.setView(game);