Merge branch 'master' of https://github.com/matteodelabre/projet-cmi
This commit is contained in:
commit
9130adec55
|
@ -3,7 +3,7 @@ project(ptf)
|
||||||
|
|
||||||
# Inclusion des fichiers d'en-tête et de source
|
# Inclusion des fichiers d'en-tête et de source
|
||||||
include_directories(include)
|
include_directories(include)
|
||||||
file(GLOB SOURCES "src/*.cpp" "src/*.c")
|
file(GLOB SOURCES "src/*.cpp" "src/*.c" "src/util/*.cpp")
|
||||||
|
|
||||||
# Affichage de tous les avertisements
|
# Affichage de tous les avertisements
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
|
|
|
@ -17,10 +17,15 @@ public:
|
||||||
Block();
|
Block();
|
||||||
virtual ~Block();
|
virtual ~Block();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clone cet objet en un objet avec les mêmes propriétés
|
||||||
|
*/
|
||||||
|
virtual ObjectPtr clone() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chargement de l'objet depuis le fichier donné
|
* Chargement de l'objet depuis le fichier donné
|
||||||
*/
|
*/
|
||||||
static std::shared_ptr<Object> load(std::ifstream& file);
|
static ObjectPtr load(std::ifstream& file);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dessin du bloc dans la fenêtre donnée
|
* Dessin du bloc dans la fenêtre donnée
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#ifndef __PTF_GAME_HPP__
|
#ifndef __PTF_EDITOR_HPP__
|
||||||
#define __PTF_GAME_HPP__
|
#define __PTF_EDITOR_HPP__
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "level.hpp"
|
#include "level.hpp"
|
||||||
|
#include "util/widget_timer.hpp"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* La classe Editor permet l'édition de
|
* La classe Editor permet l'édition de
|
||||||
|
@ -11,6 +12,7 @@
|
||||||
class Editor : public Level {
|
class Editor : public Level {
|
||||||
private:
|
private:
|
||||||
std::unordered_map<ObjectPtr, bool> selection;
|
std::unordered_map<ObjectPtr, bool> selection;
|
||||||
|
WidgetTimer widget_timer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ajoute un objet du type actuel à la position donnée
|
* Ajoute un objet du type actuel à la position donnée
|
||||||
|
@ -30,6 +32,11 @@ private:
|
||||||
*/
|
*/
|
||||||
bool updateSelection(sf::Vector2f position);
|
bool updateSelection(sf::Vector2f position);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lance le test du niveau
|
||||||
|
*/
|
||||||
|
void testLevel();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Dessine tous les objets, le fond et
|
* Dessine tous les objets, le fond et
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define __PTF_GAME_HPP__
|
#define __PTF_GAME_HPP__
|
||||||
|
|
||||||
#include "level.hpp"
|
#include "level.hpp"
|
||||||
|
#include "editor.hpp"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* La classe Game gère l'affichage et les objets
|
* La classe Game gère l'affichage et les objets
|
||||||
|
@ -9,7 +10,10 @@
|
||||||
*/
|
*/
|
||||||
class Game : public Level {
|
class Game : public Level {
|
||||||
private:
|
private:
|
||||||
|
WidgetTimer widget_timer;
|
||||||
sf::Time next_frame_time;
|
sf::Time next_frame_time;
|
||||||
|
bool test_mode;
|
||||||
|
std::shared_ptr<View> return_view;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Met à jour les objets du jeu pour
|
* Met à jour les objets du jeu pour
|
||||||
|
@ -17,6 +21,13 @@ private:
|
||||||
*/
|
*/
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Dessine tous les objets, le fond et
|
||||||
|
* l'interface de jeu
|
||||||
|
*/
|
||||||
|
virtual void draw();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Game(Manager& manager);
|
Game(Manager& manager);
|
||||||
virtual ~Game();
|
virtual ~Game();
|
||||||
|
@ -31,6 +42,12 @@ public:
|
||||||
* cette vue
|
* cette vue
|
||||||
*/
|
*/
|
||||||
void frame();
|
void frame();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mise en mode test : l'appui sur espace renvoie
|
||||||
|
* vers l'éditeur donné
|
||||||
|
*/
|
||||||
|
void setTestMode(std::shared_ptr<View> set_return_view);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
class Level : public View {
|
class Level : public View {
|
||||||
private:
|
private:
|
||||||
std::string name;
|
sf::String name;
|
||||||
int total_time;
|
int total_time;
|
||||||
sf::Sprite background;
|
sf::Sprite background;
|
||||||
|
|
||||||
|
@ -45,23 +45,33 @@ public:
|
||||||
/**
|
/**
|
||||||
* Récupère le nom du niveau
|
* Récupère le nom du niveau
|
||||||
*/
|
*/
|
||||||
std::string getName();
|
sf::String getName() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifie le nom du niveau
|
* Modifie le nom du niveau
|
||||||
*/
|
*/
|
||||||
void setName(std::string set_name);
|
void setName(sf::String set_name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Récupère le temps total alloué pour terminer le niveau
|
* Récupère le temps total alloué pour terminer le niveau
|
||||||
*/
|
*/
|
||||||
int getTotalTime();
|
int getTotalTime() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifie le temps total du niveau
|
* Modifie le temps total du niveau
|
||||||
*/
|
*/
|
||||||
void setTotalTime(int set_total_time);
|
void setTotalTime(int set_total_time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère le fond du niveau
|
||||||
|
*/
|
||||||
|
sf::Sprite getBackground() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifie le fond du niveau
|
||||||
|
*/
|
||||||
|
void setBackground(sf::Sprite set_background);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Récupère la liste des objets
|
* Récupère la liste des objets
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,7 +14,7 @@ private:
|
||||||
sf::RenderWindow window;
|
sf::RenderWindow window;
|
||||||
sf::Clock clock;
|
sf::Clock clock;
|
||||||
sf::View window_view;
|
sf::View window_view;
|
||||||
std::string title;
|
sf::String title;
|
||||||
|
|
||||||
ResourceManager resource_manager;
|
ResourceManager resource_manager;
|
||||||
std::vector<sf::Event> events;
|
std::vector<sf::Event> events;
|
||||||
|
@ -29,6 +29,11 @@ public:
|
||||||
*/
|
*/
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renvoie la vue actuelle du jeu
|
||||||
|
*/
|
||||||
|
std::shared_ptr<View> getView();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Charge la vue donnée dans le jeu
|
* Charge la vue donnée dans le jeu
|
||||||
*/
|
*/
|
||||||
|
@ -68,12 +73,12 @@ public:
|
||||||
/**
|
/**
|
||||||
* Renvoie le titre actuel de la fenêtre
|
* Renvoie le titre actuel de la fenêtre
|
||||||
*/
|
*/
|
||||||
std::string getTitle();
|
sf::String getTitle();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifie le titre actuel de la fenêtre
|
* Modifie le titre actuel de la fenêtre
|
||||||
*/
|
*/
|
||||||
void setTitle(std::string set_title);
|
void setTitle(sf::String set_title);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renvoie un booléen attestant de l'appui sur la
|
* Renvoie un booléen attestant de l'appui sur la
|
||||||
|
|
|
@ -45,11 +45,16 @@ public:
|
||||||
Object();
|
Object();
|
||||||
virtual ~Object();
|
virtual ~Object();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clone cet objet en un objet avec les mêmes propriétés
|
||||||
|
*/
|
||||||
|
virtual ObjectPtr clone() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Charge les propriétés communes à tous les objets
|
* Charge les propriétés communes à tous les objets
|
||||||
* depuis le fichier donné dans l'objet donné
|
* depuis le fichier donné dans l'objet donné
|
||||||
*/
|
*/
|
||||||
static void load(std::ifstream& file, std::shared_ptr<Object> object);
|
static void load(std::ifstream& file, ObjectPtr object);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dessine l'objet dans la fenêtre donnée
|
* Dessine l'objet dans la fenêtre donnée
|
||||||
|
|
|
@ -24,10 +24,15 @@ public:
|
||||||
Player();
|
Player();
|
||||||
virtual ~Player();
|
virtual ~Player();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clone cet objet en un objet avec les mêmes propriétés
|
||||||
|
*/
|
||||||
|
virtual ObjectPtr clone() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chargement de l'objet depuis le fichier donné
|
* Chargement de l'objet depuis le fichier donné
|
||||||
*/
|
*/
|
||||||
static std::shared_ptr<Object> load(std::ifstream& file);
|
static ObjectPtr load(std::ifstream& file);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dessine la balle dans la fenêtre donnée
|
* Dessine la balle dans la fenêtre donnée
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
#ifndef __PTF_UTIL_WIDGET_BUTTON_HPP__
|
||||||
|
#define __PTF_UTIL_WIDGET_BUTTON_HPP__
|
||||||
|
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
#include <functional>
|
||||||
|
#include "manager.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Affiche un bouton pouvant être cliqué
|
||||||
|
*/
|
||||||
|
class WidgetButton {
|
||||||
|
private:
|
||||||
|
Manager& manager;
|
||||||
|
std::function<void(void)> click_cb;
|
||||||
|
|
||||||
|
unsigned int shape;
|
||||||
|
sf::RectangleShape button;
|
||||||
|
sf::VertexArray button_shape;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const unsigned int ARROW_UP;
|
||||||
|
static const unsigned int ARROW_DOWN;
|
||||||
|
|
||||||
|
WidgetButton(
|
||||||
|
Manager& manager, std::function<void(void)> click_cb,
|
||||||
|
sf::Vector2f size, unsigned int shape
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process l'événement et renvoie true si
|
||||||
|
* on s'en est servi
|
||||||
|
*/
|
||||||
|
bool processEvent(const sf::Event& event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dessine le widget à la position (haut-gauche) donnée
|
||||||
|
*/
|
||||||
|
void draw(sf::Vector2f position);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,58 @@
|
||||||
|
#ifndef __PTF_UTIL_WIDGET_TIMER_HPP__
|
||||||
|
#define __PTF_UTIL_WIDGET_TIMER_HPP__
|
||||||
|
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
#include <functional>
|
||||||
|
#include "util/widget_button.hpp"
|
||||||
|
#include "manager.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Affiche le compteur de temps pouvant (ou non)
|
||||||
|
* être modifié
|
||||||
|
*/
|
||||||
|
class WidgetTimer {
|
||||||
|
private:
|
||||||
|
Manager& manager;
|
||||||
|
bool can_change;
|
||||||
|
std::function<void(int)> time_left_cb;
|
||||||
|
int time_left;
|
||||||
|
|
||||||
|
sf::RectangleShape timer_zone;
|
||||||
|
sf::Text timer_seconds_text;
|
||||||
|
sf::Text timer_sep_text;
|
||||||
|
sf::Text timer_minutes_text;
|
||||||
|
|
||||||
|
WidgetButton timer_up;
|
||||||
|
WidgetButton timer_down;
|
||||||
|
|
||||||
|
public:
|
||||||
|
WidgetTimer(Manager& manager, bool can_change, std::function<void(int)> time_left_cb = std::function<void(int)>());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process l'événement et renvoie true si
|
||||||
|
* on s'en est servi
|
||||||
|
*/
|
||||||
|
bool processEvent(const sf::Event& event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dessine le widget à la position (haut-gauche) donnée
|
||||||
|
*/
|
||||||
|
void draw(sf::Vector2f position);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Augmente le temps de 5 secondes
|
||||||
|
*/
|
||||||
|
void addTime();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Diminue le temps de 5 secondes
|
||||||
|
*/
|
||||||
|
void subtractTime();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifie le temps restant
|
||||||
|
*/
|
||||||
|
void setTimeLeft(int set_time_left);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 301 B |
|
@ -16,8 +16,12 @@ Block::Block() : Object() {
|
||||||
|
|
||||||
Block::~Block() {}
|
Block::~Block() {}
|
||||||
|
|
||||||
std::shared_ptr<Object> Block::load(std::ifstream& file) {
|
ObjectPtr Block::clone() const {
|
||||||
std::shared_ptr<Object> object = std::shared_ptr<Object>(new Block);
|
return ObjectPtr(new Block(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectPtr Block::load(std::ifstream& file) {
|
||||||
|
ObjectPtr object = ObjectPtr(new Block);
|
||||||
|
|
||||||
// lecture des propriétés communes des objets
|
// lecture des propriétés communes des objets
|
||||||
Object::load(file, object);
|
Object::load(file, object);
|
||||||
|
|
|
@ -1,28 +1,32 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
#include "editor.hpp"
|
#include "editor.hpp"
|
||||||
|
#include "game.hpp"
|
||||||
#include "block.hpp"
|
#include "block.hpp"
|
||||||
#include "constants.hpp"
|
#include "constants.hpp"
|
||||||
|
|
||||||
Editor::Editor(Manager& manager) : Level(manager) {
|
Editor::Editor(Manager& manager) : Level(manager),
|
||||||
// activation de la synchronisation verticale
|
widget_timer(manager, true, std::bind(&Editor::setTotalTime, this, std::placeholders::_1)) {}
|
||||||
// car, dans l'éditeur, nous n'avons besoin que de dessiner
|
|
||||||
// (pas de mise à jour physique)
|
|
||||||
manager.getWindow().setVerticalSyncEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Editor::~Editor() {}
|
Editor::~Editor() {}
|
||||||
|
|
||||||
void Editor::load(std::ifstream& file) {
|
void Editor::load(std::ifstream& file) {
|
||||||
Level::load(file);
|
Level::load(file);
|
||||||
manager.setTitle("Edition de " + getName());
|
manager.setTitle(sf::String(L"Édition de ") + getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::frame() {
|
void Editor::frame() {
|
||||||
const std::vector<sf::Event>& events = manager.getEvents();
|
const std::vector<sf::Event>& events = manager.getEvents();
|
||||||
|
|
||||||
|
// traitement des événements
|
||||||
for (unsigned int i = 0; i < events.size(); i++) {
|
for (unsigned int i = 0; i < events.size(); i++) {
|
||||||
const sf::Event& event = events[i];
|
const sf::Event& event = events[i];
|
||||||
|
|
||||||
|
// traitement des événements du widget timer
|
||||||
|
if (widget_timer.processEvent(event)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// lorsque l'on clique dans l'éditeur
|
// lorsque l'on clique dans l'éditeur
|
||||||
if (event.type == sf::Event::MouseButtonPressed) {
|
if (event.type == sf::Event::MouseButtonPressed) {
|
||||||
sf::Vector2f position(event.mouseButton.x, event.mouseButton.y);
|
sf::Vector2f position(event.mouseButton.x, event.mouseButton.y);
|
||||||
|
@ -33,25 +37,36 @@ void Editor::frame() {
|
||||||
if (!updateSelection(position)) {
|
if (!updateSelection(position)) {
|
||||||
addObject(position);
|
addObject(position);
|
||||||
}
|
}
|
||||||
}
|
} else if (event.mouseButton.button == sf::Mouse::Right) {
|
||||||
|
|
||||||
if (event.mouseButton.button == sf::Mouse::Right) {
|
|
||||||
// clic droit : on supprime l'objet pointé
|
// clic droit : on supprime l'objet pointé
|
||||||
removeObject(position);
|
removeObject(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gestion des touches
|
||||||
|
if (event.type == sf::Event::KeyPressed) {
|
||||||
|
// appui sur espace : test du niveau en cours d'édition
|
||||||
|
if (event.key.code == sf::Keyboard::Space) {
|
||||||
|
testLevel();
|
||||||
|
return; // important : ne pas dessiner la frame
|
||||||
|
// on risque d'avoir perdu le pointeur en changeant de vue
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dessin de la frame
|
||||||
draw();
|
draw();
|
||||||
|
sf::sleep(sf::seconds(1.f / 60));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::draw() {
|
void Editor::draw() {
|
||||||
Level::draw();
|
Level::draw();
|
||||||
|
|
||||||
sf::RenderWindow& window = manager.getWindow();
|
sf::RenderWindow& window = manager.getWindow();
|
||||||
sf::View window_view = manager.getWindowView();
|
sf::View window_view = manager.getWindowView();
|
||||||
sf::Color selection_color(255, 50, 41);
|
sf::Color selection_color(255, 50, 41);
|
||||||
|
|
||||||
// on dessine des carrés de sélection autour des objets sélectionnés
|
// dessin de la sélection autour des objets sélectionnés
|
||||||
for (auto iter = selection.begin(); iter != selection.end(); iter++) {
|
for (auto iter = selection.begin(); iter != selection.end(); iter++) {
|
||||||
sf::VertexArray selection(sf::LinesStrip, 5);
|
sf::VertexArray selection(sf::LinesStrip, 5);
|
||||||
std::unique_ptr<sf::FloatRect> aabb = iter->first->getAABB();
|
std::unique_ptr<sf::FloatRect> aabb = iter->first->getAABB();
|
||||||
|
@ -70,6 +85,10 @@ void Editor::draw() {
|
||||||
window.draw(selection);
|
window.draw(selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dessin du widget timer
|
||||||
|
widget_timer.setTimeLeft(getTotalTime());
|
||||||
|
widget_timer.draw(sf::Vector2f(window_view.getSize().x / 2 - 50, 0));
|
||||||
|
|
||||||
// menu
|
// menu
|
||||||
sf::RectangleShape menu(sf::Vector2f(window_view.getSize().x, 64));
|
sf::RectangleShape menu(sf::Vector2f(window_view.getSize().x, 64));
|
||||||
menu.setPosition(sf::Vector2f(0, window_view.getSize().y - 64));
|
menu.setPosition(sf::Vector2f(0, window_view.getSize().y - 64));
|
||||||
|
@ -87,7 +106,7 @@ void Editor::addObject(sf::Vector2f position) {
|
||||||
position *= Constants::GRID;
|
position *= Constants::GRID;
|
||||||
|
|
||||||
// TODO: ajouter un objet du type choisi, pas uniquement de bloc
|
// TODO: ajouter un objet du type choisi, pas uniquement de bloc
|
||||||
std::shared_ptr<Object> object = std::shared_ptr<Object>(new Block);
|
ObjectPtr object = ObjectPtr(new Block);
|
||||||
object->setPosition(position);
|
object->setPosition(position);
|
||||||
|
|
||||||
// avant d'ajouter l'objet, on vérifie qu'il ne soit
|
// avant d'ajouter l'objet, on vérifie qu'il ne soit
|
||||||
|
@ -149,3 +168,30 @@ bool Editor::updateSelection(sf::Vector2f position) {
|
||||||
|
|
||||||
return has_changed;
|
return has_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Editor::testLevel() {
|
||||||
|
std::shared_ptr<Game> game = std::shared_ptr<Game>(new Game(manager));
|
||||||
|
|
||||||
|
// copie des propriétés
|
||||||
|
game->setName(getName());
|
||||||
|
game->setTotalTime(getTotalTime());
|
||||||
|
game->setBackground(getBackground());
|
||||||
|
|
||||||
|
// copie des objets du niveau vers le jeu
|
||||||
|
std::vector<ObjectPtr>& objects = getObjects();
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < objects.size(); i++) {
|
||||||
|
game->getObjects().push_back(objects[i]->clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// copie de la zone de jeu
|
||||||
|
std::vector<std::pair<float, float>>& zone = getZone();
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < zone.size(); i++) {
|
||||||
|
game->getZone().push_back(zone[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// mise en mode test
|
||||||
|
game->setTestMode(manager.getView());
|
||||||
|
manager.setView(game);
|
||||||
|
}
|
||||||
|
|
40
src/game.cpp
40
src/game.cpp
|
@ -1,13 +1,10 @@
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
#include "constants.hpp"
|
#include "constants.hpp"
|
||||||
|
|
||||||
Game::Game(Manager& manager) : Level(manager), next_frame_time(manager.getCurrentTime()) {
|
Game::Game(Manager& manager) : Level(manager),
|
||||||
// on s'assure que la synchronisation verticale soit
|
widget_timer(manager, false),
|
||||||
// bien désactivée : on s'occupe de la limitation du
|
next_frame_time(manager.getCurrentTime()),
|
||||||
// framerate manuellement dans la fonction frame pour mettre
|
test_mode(false), return_view(nullptr) {}
|
||||||
// une mise à jour fluide de la physique du jeu
|
|
||||||
manager.getWindow().setVerticalSyncEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
Game::~Game() {}
|
Game::~Game() {}
|
||||||
|
|
||||||
|
@ -17,8 +14,22 @@ void Game::load(std::ifstream& file) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::frame() {
|
void Game::frame() {
|
||||||
|
const std::vector<sf::Event>& events = manager.getEvents();
|
||||||
sf::Time current_time = manager.getCurrentTime();
|
sf::Time current_time = manager.getCurrentTime();
|
||||||
|
|
||||||
|
// traitement des événements
|
||||||
|
for (unsigned int i = 0; i < events.size(); i++) {
|
||||||
|
const sf::Event& event = events[i];
|
||||||
|
|
||||||
|
// appui sur espace en mode test : retour à l'éditeur
|
||||||
|
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Space && test_mode) {
|
||||||
|
test_mode = false;
|
||||||
|
manager.setView(return_view);
|
||||||
|
return; // important : ne pas dessiner la frame
|
||||||
|
// on risque d'avoir perdu le pointeur en changeant de vue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (current_time >= next_frame_time) {
|
if (current_time >= next_frame_time) {
|
||||||
// si nous sommes en retard ou dans les temps
|
// si nous sommes en retard ou dans les temps
|
||||||
// on replanifie la prochaine frame
|
// on replanifie la prochaine frame
|
||||||
|
@ -38,6 +49,16 @@ void Game::frame() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Game::draw() {
|
||||||
|
Level::draw();
|
||||||
|
|
||||||
|
sf::View window_view = manager.getWindowView();
|
||||||
|
|
||||||
|
// dessin du widget
|
||||||
|
widget_timer.setTimeLeft(getTotalTime());
|
||||||
|
widget_timer.draw(sf::Vector2f(window_view.getSize().x / 2 - 50, 0));
|
||||||
|
}
|
||||||
|
|
||||||
void Game::update() {
|
void Game::update() {
|
||||||
std::vector<CollisionData> colliding;
|
std::vector<CollisionData> colliding;
|
||||||
|
|
||||||
|
@ -84,3 +105,8 @@ void Game::update() {
|
||||||
getObjects()[i]->updateVelocity(manager, getObjects(), Constants::PHYSICS_TIME.asSeconds() / 2);
|
getObjects()[i]->updateVelocity(manager, getObjects(), Constants::PHYSICS_TIME.asSeconds() / 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Game::setTestMode(std::shared_ptr<View> set_return_view) {
|
||||||
|
return_view = set_return_view;
|
||||||
|
test_mode = true;
|
||||||
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
* à des instances qui seront utilisées pour la
|
* à des instances qui seront utilisées pour la
|
||||||
* construction d'autres objets de ces types
|
* construction d'autres objets de ces types
|
||||||
*/
|
*/
|
||||||
std::map<unsigned int, std::function<std::shared_ptr<Object>(std::ifstream&)>> object_type_map = {
|
std::map<unsigned int, std::function<ObjectPtr(std::ifstream&)>> object_type_map = {
|
||||||
{Player::TYPE_ID, Player::load},
|
{Player::TYPE_ID, Player::load},
|
||||||
{Block::TYPE_ID, Block::load}
|
{Block::TYPE_ID, Block::load}
|
||||||
};
|
};
|
||||||
|
@ -49,7 +49,9 @@ void Level::load(std::ifstream& file) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// lecture du nom du niveau
|
// lecture du nom du niveau
|
||||||
std::getline(file, name, '\0');
|
std::string std_name;
|
||||||
|
std::getline(file, std_name, '\0');
|
||||||
|
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));
|
||||||
|
@ -129,22 +131,34 @@ void Level::draw() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Level::getName() {
|
sf::String Level::getName() const {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Level::setName(std::string set_name) {
|
void Level::setName(sf::String set_name) {
|
||||||
name = set_name;
|
name = set_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Level::getTotalTime() {
|
int Level::getTotalTime() const {
|
||||||
return total_time;
|
return total_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Level::setTotalTime(int set_total_time) {
|
void Level::setTotalTime(int set_total_time) {
|
||||||
|
// faisons rester le temps entre 10s et 59:59
|
||||||
|
set_total_time = std::min(set_total_time, 3599);
|
||||||
|
set_total_time = std::max(set_total_time, 10);
|
||||||
|
|
||||||
total_time = set_total_time;
|
total_time = set_total_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sf::Sprite Level::getBackground() const {
|
||||||
|
return background;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Level::setBackground(sf::Sprite set_background) {
|
||||||
|
background = set_background;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<ObjectPtr>& Level::getObjects() {
|
std::vector<ObjectPtr>& Level::getObjects() {
|
||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,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, 2)
|
||||||
), window_view(window.getView()), title(""), view(NULL) {}
|
), window_view(window.getView()), title(sf::String(L"")), view(NULL) {}
|
||||||
|
|
||||||
void Manager::start() {
|
void Manager::start() {
|
||||||
while (window.isOpen()) {
|
while (window.isOpen()) {
|
||||||
|
@ -39,6 +39,10 @@ void Manager::start() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<View> Manager::getView() {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
void Manager::setView(std::shared_ptr<View> set_view) {
|
void Manager::setView(std::shared_ptr<View> set_view) {
|
||||||
view = set_view;
|
view = set_view;
|
||||||
}
|
}
|
||||||
|
@ -68,17 +72,17 @@ void Manager::setWindowView(sf::View set_window_view) {
|
||||||
window_view = set_window_view;
|
window_view = set_window_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Manager::getTitle() {
|
sf::String Manager::getTitle() {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::setTitle(std::string set_title) {
|
void Manager::setTitle(sf::String set_title) {
|
||||||
title = set_title;
|
title = set_title;
|
||||||
|
|
||||||
if (title.empty()) {
|
if (title.isEmpty()) {
|
||||||
window.setTitle("Skizzle");
|
window.setTitle(sf::String(L"Skizzle"));
|
||||||
} else {
|
} else {
|
||||||
window.setTitle("Skizzle - " + title);
|
window.setTitle(sf::String(L"Skizzle ‒ ") + title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ Object::Object() :
|
||||||
|
|
||||||
Object::~Object() {}
|
Object::~Object() {}
|
||||||
|
|
||||||
void Object::load(std::ifstream& file, std::shared_ptr<Object> object) {
|
void Object::load(std::ifstream& file, ObjectPtr object) {
|
||||||
// lecture de la position de l'objet
|
// lecture de la position de l'objet
|
||||||
float pos_x, pos_y;
|
float pos_x, pos_y;
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,12 @@ Player::Player() : Object() {
|
||||||
|
|
||||||
Player::~Player() {}
|
Player::~Player() {}
|
||||||
|
|
||||||
std::shared_ptr<Object> Player::load(std::ifstream& file) {
|
ObjectPtr Player::clone() const {
|
||||||
std::shared_ptr<Object> object = std::shared_ptr<Object>(new Player);
|
return ObjectPtr(new Player(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectPtr Player::load(std::ifstream& file) {
|
||||||
|
ObjectPtr object = ObjectPtr(new Player);
|
||||||
std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>(object);
|
std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>(object);
|
||||||
|
|
||||||
// lecture du numéro de joueur
|
// lecture du numéro de joueur
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
#include "util/widget_button.hpp"
|
||||||
|
|
||||||
|
const unsigned int WidgetButton::ARROW_UP = 0;
|
||||||
|
const unsigned int WidgetButton::ARROW_DOWN = 1;
|
||||||
|
|
||||||
|
const sf::Color ARROW_COLOR = sf::Color(33, 33, 33);
|
||||||
|
const sf::Color CLICKED_COLOR = sf::Color(190, 190, 190);
|
||||||
|
const sf::Color REST_COLOR = sf::Color(230, 230, 230);
|
||||||
|
|
||||||
|
WidgetButton::WidgetButton(
|
||||||
|
Manager& manager, std::function<void(void)> click_cb,
|
||||||
|
sf::Vector2f size, unsigned int shape
|
||||||
|
) : manager(manager), click_cb(click_cb), shape(shape), button(size) {
|
||||||
|
if (shape == WidgetButton::ARROW_UP || shape == WidgetButton::ARROW_DOWN) {
|
||||||
|
button_shape.setPrimitiveType(sf::Triangles);
|
||||||
|
button_shape.resize(3);
|
||||||
|
|
||||||
|
button_shape[0].color = ARROW_COLOR;
|
||||||
|
button_shape[1].color = ARROW_COLOR;
|
||||||
|
button_shape[2].color = ARROW_COLOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WidgetButton::processEvent(const sf::Event& event) {
|
||||||
|
if (event.type == sf::Event::MouseButtonPressed) {
|
||||||
|
sf::Vector2f position(event.mouseButton.x, event.mouseButton.y);
|
||||||
|
|
||||||
|
if (event.mouseButton.button == sf::Mouse::Left) {
|
||||||
|
// clic gauche sur le bouton : appel de la callback
|
||||||
|
if (button.getGlobalBounds().contains(position)) {
|
||||||
|
click_cb();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetButton::draw(sf::Vector2f position) {
|
||||||
|
sf::RenderWindow& window = manager.getWindow();
|
||||||
|
|
||||||
|
// positionnement du bouton
|
||||||
|
button.setPosition(position);
|
||||||
|
sf::FloatRect box = button.getGlobalBounds();
|
||||||
|
sf::Vector2f center(box.left + box.width / 2, box.top + box.height / 2);
|
||||||
|
|
||||||
|
if (shape == WidgetButton::ARROW_UP) {
|
||||||
|
button_shape[0].position = center + sf::Vector2f(-5, 2);
|
||||||
|
button_shape[1].position = center + sf::Vector2f(5, 2);
|
||||||
|
button_shape[2].position = center + sf::Vector2f(0, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shape == WidgetButton::ARROW_DOWN) {
|
||||||
|
button_shape[0].position = center + sf::Vector2f(-5, -2);
|
||||||
|
button_shape[1].position = center + sf::Vector2f(5, -2);
|
||||||
|
button_shape[2].position = center + sf::Vector2f(0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// coloration des boutons si enfoncement
|
||||||
|
button.setFillColor(REST_COLOR);
|
||||||
|
|
||||||
|
if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
|
||||||
|
sf::Vector2f mouse_position = (sf::Vector2f) sf::Mouse::getPosition(window);
|
||||||
|
|
||||||
|
if (button.getGlobalBounds().contains(mouse_position)) {
|
||||||
|
button.setFillColor(CLICKED_COLOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.draw(button);
|
||||||
|
window.draw(button_shape);
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
#include <cmath>
|
||||||
|
#include "util/widget_timer.hpp"
|
||||||
|
|
||||||
|
WidgetTimer::WidgetTimer(Manager& manager, bool can_change, std::function<void(int)> time_left_cb) :
|
||||||
|
manager(manager), can_change(can_change), time_left_cb(time_left_cb),
|
||||||
|
timer_zone(sf::Vector2f(100, 32)),
|
||||||
|
timer_up(manager, std::bind(&WidgetTimer::addTime, this), sf::Vector2f(30, 16), WidgetButton::ARROW_UP),
|
||||||
|
timer_down(manager, std::bind(&WidgetTimer::subtractTime, this), sf::Vector2f(30, 16), WidgetButton::ARROW_DOWN) {
|
||||||
|
|
||||||
|
// initialisation des formes
|
||||||
|
timer_seconds_text.setFont(manager.getResourceManager().getFont("monoid.ttf"));
|
||||||
|
timer_seconds_text.setCharacterSize(18);
|
||||||
|
timer_seconds_text.setColor(sf::Color::Black);
|
||||||
|
|
||||||
|
timer_sep_text.setString(":");
|
||||||
|
timer_sep_text.setFont(manager.getResourceManager().getFont("monoid.ttf"));
|
||||||
|
timer_sep_text.setCharacterSize(18);
|
||||||
|
timer_sep_text.setColor(sf::Color::Black);
|
||||||
|
|
||||||
|
timer_minutes_text.setFont(manager.getResourceManager().getFont("monoid.ttf"));
|
||||||
|
timer_minutes_text.setCharacterSize(18);
|
||||||
|
timer_minutes_text.setColor(sf::Color::Black);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WidgetTimer::processEvent(const sf::Event& event) {
|
||||||
|
// si le timer n'est pas modifiable, pas d'évent à gérer
|
||||||
|
if (!can_change) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// gestion des boutons
|
||||||
|
if (timer_up.processEvent(event)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timer_down.processEvent(event)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.type == sf::Event::MouseButtonPressed) {
|
||||||
|
sf::Vector2f position(event.mouseButton.x, event.mouseButton.y);
|
||||||
|
|
||||||
|
// clic dans le widget : ne rien faire, mais empêcher le traversement
|
||||||
|
if (timer_zone.getGlobalBounds().contains(position)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.type == sf::Event::MouseWheelScrolled && event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel) {
|
||||||
|
// scroll sur le timer : modification du temps alloué au niveau
|
||||||
|
sf::Vector2f position(event.mouseWheelScroll.x, event.mouseWheelScroll.y);
|
||||||
|
|
||||||
|
if (timer_zone.getGlobalBounds().contains(position)) {
|
||||||
|
time_left_cb(time_left + round(event.mouseWheelScroll.delta * 10));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetTimer::draw(sf::Vector2f position) {
|
||||||
|
sf::RenderWindow& window = manager.getWindow();
|
||||||
|
|
||||||
|
// zone de fond du timer
|
||||||
|
timer_zone.setPosition(position);
|
||||||
|
window.draw(timer_zone);
|
||||||
|
|
||||||
|
// affichage du temps du niveau
|
||||||
|
sf::String minutes = std::to_string(time_left / 60);
|
||||||
|
sf::String seconds = std::to_string(time_left % 60);
|
||||||
|
|
||||||
|
// ajout d'un zéro devant les secondes si nécessaire
|
||||||
|
if (minutes.getSize() == 1) {
|
||||||
|
minutes = "0" + minutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seconds.getSize() == 1) {
|
||||||
|
seconds = "0" + seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer_minutes_text.setString(minutes);
|
||||||
|
timer_seconds_text.setString(seconds);
|
||||||
|
|
||||||
|
float base_x = can_change ? 30 : 45;
|
||||||
|
timer_sep_text.setPosition(position + sf::Vector2f(base_x, 6));
|
||||||
|
timer_seconds_text.setPosition(position + sf::Vector2f(base_x + 8, 6));
|
||||||
|
timer_minutes_text.setPosition(position + sf::Vector2f(
|
||||||
|
base_x - 3 - floor(timer_minutes_text.getGlobalBounds().width), 6
|
||||||
|
));
|
||||||
|
|
||||||
|
window.draw(timer_sep_text);
|
||||||
|
window.draw(timer_seconds_text);
|
||||||
|
window.draw(timer_minutes_text);
|
||||||
|
|
||||||
|
// interface de modification du temps
|
||||||
|
if (can_change) {
|
||||||
|
timer_up.draw(position + sf::Vector2f(70, 0));
|
||||||
|
timer_down.draw(position + sf::Vector2f(70, 16));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetTimer::addTime() {
|
||||||
|
time_left_cb(time_left + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetTimer::subtractTime() {
|
||||||
|
time_left_cb(time_left - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetTimer::setTimeLeft(int set_time_left) {
|
||||||
|
time_left = set_time_left;
|
||||||
|
}
|
Loading…
Reference in New Issue