This commit is contained in:
Rémi Cérès 2016-04-06 15:35:37 +02:00
commit 9130adec55
22 changed files with 486 additions and 49 deletions

2
CMakeLists.txt vendored
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,16 +24,21 @@ 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
*/ */
virtual void draw(Manager& manager); virtual void draw(Manager& manager);
/** /**
* Met à jour la position de l'objet selon sa * Met à jour la position de l'objet selon sa
* vitesse actuelle * vitesse actuelle

View File

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

View File

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

BIN
res/monoid.ttf Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 B

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

113
src/util/widget_timer.cpp Normal file
View File

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