Nettoyage et améliorations du menu

This commit is contained in:
Mattéo Delabre 2016-04-09 02:32:11 +02:00
parent 6e51081001
commit dc8a0e05d8
15 changed files with 265 additions and 226 deletions

View File

@ -84,14 +84,15 @@ public:
virtual ~Editor();
/**
* Demande le passage à la frame suivante sur cette vue
* Appelé par le manager lorsque la vue commence à
* être utilisée
*/
virtual void frame();
virtual void begin();
/**
* Charge un niveau de jeu depuis le fichier donné
* Demande le passage à la frame suivante sur cette vue
*/
virtual void load(std::ifstream& file);
virtual void frame(const std::vector<sf::Event>& events);
};
#endif

View File

@ -43,14 +43,15 @@ public:
virtual ~Game();
/**
* Charge un niveau de jeu depuis le fichier donné
* Appelé par le manager lorsque la vue commence à
* être utilisée
*/
virtual void load(std::ifstream& file);
virtual void begin();
/**
* Demande le passage à la frame suivante sur cette vue
*/
virtual void frame();
virtual void frame(const std::vector<sf::Event>& events);
/**
* Mise en mode test : l'appui sur espace renvoie

View File

@ -19,11 +19,13 @@ private:
sf::String name;
int total_time;
sf::Sprite background;
std::string music_name;
std::vector<ObjectPtr> objects;
std::vector<std::pair<float, float>> zone;
protected:
/**
* Dessine tous les objets et le fond à l'écran
*/
@ -60,10 +62,16 @@ public:
*/
virtual void save();
/**
* Appelé par le manager lorsque la vue commence à
* être utilisée
*/
virtual void begin();
/**
* Demande le passage à la frame suivante sur cette vue
*/
virtual void frame();
virtual void frame(const std::vector<sf::Event>& events);
/**
* Récupère le nom du niveau

View File

@ -62,12 +62,6 @@ public:
*/
ResourceManager& getResourceManager();
/**
* Renvoie la liste des événements reçus pour la
* précédente frame
*/
const std::vector<sf::Event>& getEvents();
/**
* Remet la vue par défaut (zoom 1:1, origine en haut à gauche)
*/

View File

@ -2,52 +2,71 @@
#define __PTF_MENU_HPP__
#include "manager.hpp"
#include "game.hpp"
#include "editor.hpp"
#include "view.hpp"
#include "resource_manager.hpp"
#include <SFML/Audio.hpp>
#include <functional>
#include <vector>
#define NB_CHOICES 4
/**
* La classe Menu charge le menu du jeu
* et permet de choisir entre jouer, lire les règles
* et quitter.
*/
class Menu : public View {
private:
std::vector<sf::String> choices;
std::vector<std::function<void(void)>> actions;
unsigned int selection;
protected:
/**
* Traite l'événement donné
*/
virtual void processEvent(const sf::Event& event);
public:
Menu(Manager& manager);
virtual ~Menu();
/**
* Dessine le menu
* Appelé par le manager lorsque la vue commence à
* être utilisée
*/
void frame();
virtual void begin();
/**
* Permet de changer le choix sélectionné
* Dessine le menu
*/
void MoveUp();
void MoveDown();
void menu1();
void menu2();
virtual void frame(const std::vector<sf::Event>& events);
private:
//repère le choix sélectionné
int selection;
/**
* Affiche le menu principal
*/
void loadMainMenu();
int menu_nb;
/**
* Affiche le menu de choix des niveaux
*/
void loadLevelMenu();
int positionY;
std::vector<std::function<void()>> menu[NB_CHOICES];
sf::Font font;
/**
* Affiche les règles du jeu
*/
void loadRules();
//tableau de textes modélisant les différents
//choix dans le menu
sf::Text choice[NB_CHOICES];
/**
* Démarre l'éditeur
*/
void launchEditor();
/**
* Démarre le jeu avec le niveau donné
*/
void launchGame(std::string name);
/**
* Quitte le jeu et le menu
*/
void quit();
};

View File

@ -10,9 +10,7 @@
*/
struct SelectorItem {
sf::String name;
sf::Sprite sprite;
sf::Sprite select_sprite;
};
/**
@ -25,7 +23,7 @@ struct SelectorCategory {
/**
* Ajoute un nouvel item dans cette catégorie
*/
void addItem(sf::String name, sf::Texture& texture, sf::Texture& select_texture);
std::shared_ptr<SelectorItem> addItem(sf::String name, sf::Texture& texture);
};
/**

View File

@ -13,14 +13,25 @@ class View {
protected:
Manager& manager;
/**
* Traite l'événement donné
*/
virtual void processEvent(const sf::Event& event) = 0;
public:
View(Manager& manager);
virtual ~View();
/**
* Appelé par le manager lorsque la vue commence à
* être utilisée
*/
virtual void begin() = 0;
/**
* Demande le passage à la frame suivante sur cette vue
*/
virtual void frame() = 0;
virtual void frame(const std::vector<sf::Event>& events);
};
#endif

Binary file not shown.

View File

@ -14,26 +14,31 @@ Editor::Editor(Manager& manager) : Level(manager), drag_mode(DragMode::NONE),
widget_timer(manager, true, std::bind(&Editor::setTotalTime, this, std::placeholders::_1)),
widget_selector(manager) {
setName("Nouveau niveau");
setTotalTime(30);
ResourceManager& resources = manager.getResourceManager();
std::shared_ptr<SelectorCategory> basic = widget_selector.addCategory("BASE");
basic->addItem("Bloc", resources.getTexture("block.png"), resources.getTexture("block_select.png"));
basic->addItem("Ball", resources.getTexture("ball.png"), resources.getTexture("block_select.png"));
basic->addItem("Block", resources.getTexture("block.png"));
basic->addItem("Player", resources.getTexture("player.tga"));
}
Editor::~Editor() {}
void Editor::load(std::ifstream& file) {
Level::load(file);
manager.setTitle(sf::String(L"Édition de ") + getName());
void Editor::begin() {
Level::begin();
manager.getWindow().setFramerateLimit(60);
}
void Editor::frame() {
// traitements généraux
Level::frame();
void Editor::frame(const std::vector<sf::Event>& events) {
// traitement des événements
Level::frame(events);
// titre de la fenêtre
manager.setTitle(sf::String(L"Édition de ") + getName());
// dessin de la frame
draw();
sf::sleep(sf::seconds(1.f / 30));
}
void Editor::processEvent(const sf::Event& event) {
@ -52,7 +57,7 @@ void Editor::processEvent(const sf::Event& event) {
// lorsque l'on clique dans l'éditeur
if (event.type == sf::Event::MouseButtonPressed) {
sf::Vector2i mouse_position(event.mouseButton.x, event.mouseButton.y);
sf::Vector2f position = convertCoords(mouse_position);
sf::Vector2f position = pixelToCoords(mouse_position);
ObjectPtr pointed_object = getObject(position);
if (event.mouseButton.button == sf::Mouse::Left) {
@ -101,7 +106,7 @@ void Editor::processEvent(const sf::Event& event) {
// lorsqu'on déplace la souris
if (event.type == sf::Event::MouseMoved) {
sf::Vector2i mouse_position(event.mouseMove.x, event.mouseMove.y);
sf::Vector2f position = convertCoords(mouse_position);
sf::Vector2f position = pixelToCoords(mouse_position);
ObjectPtr pointed_object = getObject(position);
drag_end = mouse_position;
@ -126,7 +131,7 @@ void Editor::processEvent(const sf::Event& event) {
if (event.type == sf::Event::MouseButtonReleased) {
// mode sélection rectangulaire : on applique la sélection
if (drag_mode == DragMode::SELECT_RECT) {
select(convertCoords(drag_start), convertCoords(drag_end));
select(pixelToCoords(drag_start), pixelToCoords(drag_end));
}
drag_mode = DragMode::NONE;

View File

@ -12,14 +12,17 @@ Game::Game(Manager& manager) : Level(manager),
Game::~Game() {}
void Game::load(std::ifstream& file) {
Level::load(file);
manager.setTitle(getName());
void Game::begin() {
Level::begin();
manager.getWindow().setFramerateLimit(0);
}
void Game::frame() {
// traitements généraux
Level::frame();
void Game::frame(const std::vector<sf::Event>& events) {
// traitement des événements
Level::frame(events);
// titre de la fenêtre
manager.setTitle(getName());
sf::Time current_time = manager.getCurrentTime();
@ -67,7 +70,6 @@ void Game::draw() {
}
void Game::ensureCentered() {
sf::Vector2i window_size = (sf::Vector2i) manager.getWindow().getSize();
std::vector<ObjectPtr>& objects = getObjects();
sf::Vector2f total_position;

View File

@ -17,14 +17,8 @@ std::map<unsigned int, std::function<ObjectPtr(std::ifstream&)>> object_type_map
{Block::TYPE_ID, Block::load}
};
Level::Level(Manager& manager) : View(manager), total_time(30) {
camera = manager.getWindow().getDefaultView();
camera.setCenter(0, 0);
}
Level::~Level() {
objects.clear();
}
Level::Level(Manager& manager) : View(manager) {}
Level::~Level() {}
void Level::load(std::ifstream& file) {
// vide le niveau précédent s'il y a lieu
@ -82,13 +76,10 @@ void Level::load(std::ifstream& file) {
}
// lecture des chemins de la musique et du fond
std::string music_name, background_name;
std::string background_name;
ResourceManager& resource_manager = manager.getResourceManager();
std::getline(file, music_name, '\0');
resource_manager.setMusic(music_name);
resource_manager.playMusic();
std::getline(file, background_name, '\0');
background.setTexture(resource_manager.getTexture(background_name));
@ -118,15 +109,23 @@ void Level::save() {
// TODO: faire une fonction d'enregistrement
}
void Level::frame() {
const std::vector<sf::Event>& events = manager.getEvents();
void Level::begin() {
ResourceManager& resources = manager.getResourceManager();
// traitement des événements
for (unsigned int i = 0; i < events.size(); i++) {
processEvent(events[i]);
camera = manager.getWindow().getDefaultView();
camera.setCenter(0, 0);
if (music_name != "") {
resources.setMusic(music_name);
resources.playMusic();
}
}
void Level::frame(const std::vector<sf::Event>& events) {
// traitement des événements
View::frame(events);
}
void Level::processEvent(const sf::Event& event) {
// lorsque la fenêtre est redimensionnée, mise à jour
// de la taille de la caméra

View File

@ -11,11 +11,12 @@ void Manager::start() {
while (running) {
sf::Event event;
events.clear();
std::vector<sf::Event> events;
// si un changement de vue a été demandé, on l'effectue maintenant
if (next_view != nullptr) {
view = next_view;
next_view->begin();
next_view = nullptr;
}
@ -26,7 +27,7 @@ void Manager::start() {
quit();
}
// redimensionnement de la fenêtre
// redimensionnement de la vue par défaut
if (event.type == sf::Event::Resized) {
default_view = sf::View(sf::FloatRect(
0, 0, event.size.width, event.size.height
@ -42,7 +43,7 @@ void Manager::start() {
throw std::runtime_error("Aucune vue à afficher pour le jeu");
}
view->frame();
view->frame(events);
window.display();
}
}
@ -73,10 +74,6 @@ ResourceManager& Manager::getResourceManager() {
return resource_manager;
}
const std::vector<sf::Event>& Manager::getEvents() {
return events;
}
void Manager::resetDefaultView() {
window.setView(default_view);
}
@ -86,6 +83,10 @@ sf::String Manager::getTitle() {
}
void Manager::setTitle(sf::String set_title) {
if (title == set_title) {
return;
}
title = set_title;
if (title.isEmpty()) {

View File

@ -1,106 +1,144 @@
#include "menu.hpp"
#include "editor.hpp"
#include "game.hpp"
#include <cmath>
Menu::Menu(Manager& manager) : View(manager){
const float MAX_WIDTH_PROPORTION = 1.f / 3.f;
const float PADDING = 24.f;
manager.getResourceManager().setMusic("menu.wav");
manager.getResourceManager().playMusic();
Menu::Menu(Manager& manager) : View(manager) {}
Menu::~Menu() {}
menu1();
//mise en place des propriétés des textes affichés dans le menu
choice[0].setFont(manager.getResourceManager().getFont("raleway.ttf"));
choice[0].setColor(sf::Color::Red);
choice[0].setPosition(sf::Vector2f(positionY, 400/(NB_CHOICES + 1)));
void Menu::begin() {
ResourceManager& resources = manager.getResourceManager();
for(int i=1; i < NB_CHOICES; i++)
{
choice[i].setFont(manager.getResourceManager().getFont("raleway.ttf"));
choice[i].setColor(sf::Color::White);
choice[i].setPosition(sf::Vector2f(positionY, 400/((NB_CHOICES + 1))*(i+1)));
}
loadMainMenu();
resources.setMusic("menu.wav");
resources.playMusic();
//choix sélectionné à l'ouverture du menu
selection = 0;
manager.getWindow().setFramerateLimit(60);
}
Menu::~Menu(){
}
void Menu::frame(const std::vector<sf::Event>& events) {
// traitement des événements
View::frame(events);
void Menu::menu1(){
menu_nb = 1;
positionY = 460;
// titre de la fenêtitre
manager.setTitle("");
//mise en place des textes des choix
choice[0].setString("Jouer");
choice[1].setString("Regles du jeu");
choice[2].setString("Creer un niveau");
choice[3].setString("Quitter");
}
void Menu::menu2(){
menu_nb = 2;
positionY = 300;
//mise en place des textes des choix
choice[0].setString("Tutoriel");
choice[1].setString("Niveau 1");
choice[2].setString("Niveau 2");
}
void Menu::MoveUp()
{
//change la couleur du choix sélectionné
if(selection-1 >= 0)
{
choice[selection].setColor(sf::Color::White);
selection--;
choice[selection].setColor(sf::Color::Red);
}
}
void Menu::MoveDown()
{
//change la couleur du choix sélectionné
if(selection+1 < NB_CHOICES)
{
choice[selection].setColor(sf::Color::White);
selection++;
choice[selection].setColor(sf::Color::Red);
}
}
void Menu::frame(){
// affichage du menu
sf::RenderWindow& window = manager.getWindow();
sf::Vector2f size = (sf::Vector2f) window.getSize();
sf::Font font = manager.getResourceManager().getFont("raleway.ttf");
window.clear(sf::Color(66, 40, 245));
// TODO: dessiner l'image du fond
const std::vector<sf::Event>& events = manager.getEvents();
// on crée les textes pour chaque choix et on les dessine
float step = size.y / (choices.size() + 1);
int font_size = std::max((int) std::floor(step - PADDING), 12);
for (unsigned int i = 0; i < events.size(); i++) {
const sf::Event& event = events[i];
for (unsigned int i = 0; i < choices.size(); i++) {
sf::Text label(choices[i], font, 32);
sf::Vector2f position(
(1 - MAX_WIDTH_PROPORTION) * size.x,
step * (i + 1) - font_size / 2
);
float width = label.getGlobalBounds().width;
label.setPosition(position);
label.setColor(sf::Color::White);
// si c'est le choix sélecitonné, on le souligne
if (selection == i) {
sf::RectangleShape underline(sf::Vector2f(width, 2.f));
underline.setPosition(position.x, position.y + font_size / 2 + 6);
underline.setFillColor(sf::Color::White);
window.draw(underline);
}
window.draw(label);
}
window.display();
}
void Menu::processEvent(const sf::Event& event) {
// gestion des touches
if (event.type == sf::Event::KeyPressed) {
// touche flèche haut : on passe au choix précédent
if (event.key.code == sf::Keyboard::Up) {
MoveUp();
if (selection == 0) {
selection = choices.size() - 1;
} else {
selection--;
}
}
// touche flèche bas : on passe au choix suivant
if (event.key.code == sf::Keyboard::Down) {
MoveDown();
if (selection == choices.size()) {
selection = 0;
} else {
selection++;
}
}
// touche entrée : on exécute le choix sélectionné
if (event.key.code == sf::Keyboard::Return) {
//si on se trouve dans le menu 2 permettant de choisir les niveaux
if(menu_nb == 2){
//si on choisit "tutoriel", on charge le niveau tutoriel et on
//la vue passe à Game
if(selection == 0){
std::shared_ptr<Game> game = std::shared_ptr<Game>(new Game(manager));
std::string path;
switch (selection) {
case 0:
path = "./levels/level1.dat";
break;
actions[selection]();
}
}
}
void Menu::loadMainMenu() {
choices.clear();
actions.clear();
selection = 0;
choices.push_back(sf::String(L"Jouer"));
actions.push_back(std::bind(&Menu::loadLevelMenu, this));
choices.push_back(sf::String(L"Règles du jeu"));
actions.push_back(std::bind(&Menu::loadRules, this));
choices.push_back(sf::String(L"Éditeur"));
actions.push_back(std::bind(&Menu::launchEditor, this));
choices.push_back(sf::String(L"Quitter"));
actions.push_back(std::bind(&Menu::quit, this));
}
void Menu::loadLevelMenu() {
choices.clear();
actions.clear();
selection = 0;
choices.push_back(sf::String(L"Tutoriel"));
actions.push_back(std::bind(&Menu::launchGame, this, "level1.dat"));
choices.push_back(sf::String(L"Niveau 1"));
actions.push_back(std::bind(&Menu::launchGame, this, "level2.dat"));
choices.push_back(sf::String(L"Niveau 2"));
actions.push_back(std::bind(&Menu::launchGame, this, "level3.dat"));
choices.push_back(sf::String(L"Retour"));
actions.push_back(std::bind(&Menu::loadMainMenu, this));
}
void Menu::loadRules() {
// TODO: coder l'affichage des règles
}
void Menu::launchEditor() {
std::shared_ptr<View> editor = std::shared_ptr<View>(new Editor(manager));
manager.setView(editor);
}
void Menu::launchGame(std::string name) {
std::shared_ptr<Game> game = std::shared_ptr<Game>(new Game(manager));
std::string path = "./levels/" + name;
std::ifstream file;
file.open(path, std::ios::binary | std::ios::in);
@ -108,44 +146,8 @@ void Menu::frame(){
file.close();
manager.setView(game);
}
//si on choisit "Quitter", la fenêtre se ferme
if(selection == 3){
manager.quit();
}
}
if(menu_nb == 1){
//si on choisit "jouer", la vue se met sur Lvl_menu
if(selection==0){
menu2();
}
if(selection==1){
}
//si on choisit "créer un niveau", la vue se met sur Editor
if(selection==2){
std::shared_ptr<View> editor = std::shared_ptr<View>(new Editor(manager));
manager.setView(editor);
}
//si on choisit "quitter", la fenêtre se ferme
if(selection==3){
manager.quit();
}
}
}
}
}
for(int i=0; i<NB_CHOICES; i++)
{
window.draw(choice[i]);
}
window.display();
}
void Menu::quit() {
manager.quit();
}

View File

@ -15,22 +15,20 @@ std::shared_ptr<SelectorCategory> WidgetSelector::addCategory(sf::String name) {
return cat;
}
void SelectorCategory::addItem(sf::String name, sf::Texture& texture, sf::Texture& select_texture) {
std::shared_ptr<SelectorItem> SelectorCategory::addItem(sf::String name, sf::Texture& texture) {
auto item = std::shared_ptr<SelectorItem>(new SelectorItem);
item->sprite.setTexture(texture, true);
item->select_sprite.setTexture(select_texture, true);
float width = item->sprite.getLocalBounds().width;
// mise à l'échelle si trop grand ou trop petit
if (width < 20 || width > 28) {
item->sprite.scale(24 / width, 24 / width);
item->select_sprite.scale(24 / width, 24 / width);
width = 24;
}
item->name = name;
items.push_back(item);
return item;
}
bool WidgetSelector::processEvent(const sf::Event& event) {
@ -89,16 +87,9 @@ void WidgetSelector::draw(sf::Vector2f position, sf::Vector2f size) {
PADDING + 24 + 38 * j
);
// affichage des sprites des items + le sprite
// de sélection si sélectionné
// affichage du sprite de l'item
item->sprite.setPosition(sprite_position);
item->select_sprite.setPosition(sprite_position);
window.draw(item->sprite);
if (selected == item.get()) {
window.draw(item->select_sprite);
}
}
}

View File

@ -2,3 +2,10 @@
View::View(Manager& manager) : manager(manager) {}
View::~View() {}
void View::frame(const std::vector<sf::Event>& events) {
// traitement des événements
for (unsigned int i = 0; i < events.size(); i++) {
processEvent(events[i]);
}
}