Ajout la possibilité d'interrompre la frame pour éviter segfault
This commit is contained in:
parent
ddbd125f8f
commit
c560073c5f
|
@ -49,16 +49,21 @@ private:
|
|||
void select(sf::Vector2f position, SelectionMode mode);
|
||||
void select(sf::Vector2f top_left, sf::Vector2f bottom_right);
|
||||
|
||||
/**
|
||||
* Vide la sélection
|
||||
*/
|
||||
void clearSelection();
|
||||
|
||||
/**
|
||||
* Sélectionne tout
|
||||
*/
|
||||
void selectAll();
|
||||
|
||||
/**
|
||||
* Lance le test du niveau
|
||||
*/
|
||||
void test();
|
||||
|
||||
/**
|
||||
* Traite l'événement et renvoie true si on s'en est servi
|
||||
*/
|
||||
bool processEvent(const sf::Event& event);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Dessine tous les objets, le fond et
|
||||
|
@ -66,20 +71,26 @@ protected:
|
|||
*/
|
||||
virtual void draw();
|
||||
|
||||
/**
|
||||
* Traite un événement et renvoie true si le
|
||||
* dessin de la frame doit être interrompu
|
||||
*/
|
||||
virtual bool processEvent(const sf::Event& event);
|
||||
|
||||
public:
|
||||
Editor(Manager& manager);
|
||||
virtual ~Editor();
|
||||
|
||||
/**
|
||||
* Demande le passage à la frame suivante sur cette vue,
|
||||
* renvoie true si le rendu de la frame a été interrompu
|
||||
*/
|
||||
virtual bool frame();
|
||||
|
||||
/**
|
||||
* Charge un niveau de jeu depuis le fichier donné
|
||||
*/
|
||||
virtual void load(std::ifstream& file);
|
||||
|
||||
/**
|
||||
* Demande le passage à la frame suivante sur
|
||||
* cette vue
|
||||
*/
|
||||
void frame();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -28,6 +28,12 @@ protected:
|
|||
*/
|
||||
virtual void draw();
|
||||
|
||||
/**
|
||||
* Traite un événement et renvoie true si le
|
||||
* dessin de la frame doit être interrompu
|
||||
*/
|
||||
virtual bool processEvent(const sf::Event& event);
|
||||
|
||||
public:
|
||||
Game(Manager& manager);
|
||||
virtual ~Game();
|
||||
|
@ -38,10 +44,10 @@ public:
|
|||
virtual void load(std::ifstream& file);
|
||||
|
||||
/**
|
||||
* Demande le passage à la frame suivante sur
|
||||
* cette vue
|
||||
* Demande le passage à la frame suivante sur cette vue,
|
||||
* renvoie true si le rendu de la frame a été interrompu
|
||||
*/
|
||||
void frame();
|
||||
virtual bool frame();
|
||||
|
||||
/**
|
||||
* Mise en mode test : l'appui sur espace renvoie
|
||||
|
|
|
@ -28,6 +28,12 @@ protected:
|
|||
*/
|
||||
virtual void draw();
|
||||
|
||||
/**
|
||||
* Traite un événement et renvoie true si le
|
||||
* dessin de la frame doit être interrompu
|
||||
*/
|
||||
virtual bool processEvent(const sf::Event& event) = 0;
|
||||
|
||||
public:
|
||||
Level(Manager& manager);
|
||||
virtual ~Level();
|
||||
|
@ -42,6 +48,12 @@ public:
|
|||
*/
|
||||
virtual void save();
|
||||
|
||||
/**
|
||||
* Demande le passage à la frame suivante sur
|
||||
* cette vue
|
||||
*/
|
||||
virtual bool frame();
|
||||
|
||||
/**
|
||||
* Récupère le nom du niveau
|
||||
*/
|
||||
|
@ -81,6 +93,16 @@ public:
|
|||
* Récupère la zone du niveau
|
||||
*/
|
||||
std::vector<std::pair<float, float>>& getZone();
|
||||
|
||||
/**
|
||||
* Récupère le centre de la vue
|
||||
*/
|
||||
sf::Vector2f getViewCenter();
|
||||
|
||||
/**
|
||||
* Modifie le centre de la vue
|
||||
*/
|
||||
void setViewCenter(sf::Vector2f set_view_center);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -63,12 +63,12 @@ public:
|
|||
/**
|
||||
* Renvoie la vue de la fenêtre (position centrale, taille)
|
||||
*/
|
||||
sf::View getWindowView();
|
||||
sf::View& getWindowView();
|
||||
|
||||
/**
|
||||
* Modifie la vue de la fenêtre
|
||||
*/
|
||||
void setWindowView(sf::View set_window_view);
|
||||
void setWindowView(sf::View& set_window_view);
|
||||
|
||||
/**
|
||||
* Renvoie le titre actuel de la fenêtre
|
||||
|
|
|
@ -25,11 +25,11 @@ public:
|
|||
|
||||
/**
|
||||
* Dessine le menu
|
||||
*/
|
||||
void frame();
|
||||
*/
|
||||
bool frame();
|
||||
|
||||
/**
|
||||
* Permet de changer le choix sélectionné
|
||||
* Permet de changer le choix sélectionné
|
||||
*/
|
||||
void MoveUp();
|
||||
void MoveDown();
|
||||
|
|
|
@ -18,10 +18,10 @@ public:
|
|||
virtual ~View();
|
||||
|
||||
/**
|
||||
* Demande le passage à la frame suivante sur
|
||||
* cette vue
|
||||
* Demande le passage à la frame suivante sur cette vue,
|
||||
* renvoie true si le rendu de la frame a été interrompu
|
||||
*/
|
||||
virtual void frame() = 0;
|
||||
virtual bool frame() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include "editor.hpp"
|
||||
|
@ -18,23 +19,24 @@ void Editor::load(std::ifstream& file) {
|
|||
manager.setTitle(sf::String(L"Édition de ") + getName());
|
||||
}
|
||||
|
||||
void Editor::frame() {
|
||||
const std::vector<sf::Event>& events = manager.getEvents();
|
||||
|
||||
// traitement des événements
|
||||
for (unsigned int i = 0; i < events.size(); i++) {
|
||||
processEvent(events[i]);
|
||||
bool Editor::frame() {
|
||||
// si le dessin de la frame a été interrompu par
|
||||
// le traitement événementiel, on arrête
|
||||
if (Level::frame()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// dessin de la frame
|
||||
draw();
|
||||
sf::sleep(sf::seconds(1.f / 30));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Editor::processEvent(const sf::Event& event) {
|
||||
// traitement des événements du widget timer
|
||||
if (widget_timer.processEvent(event)) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// lorsque l'on clique dans l'éditeur
|
||||
|
@ -48,12 +50,10 @@ bool Editor::processEvent(const sf::Event& event) {
|
|||
drag_start = position;
|
||||
drag_end = position;
|
||||
drag_mode = DragMode::SELECT_RECT;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// clic sur un objet : démarrage de la sélection libre
|
||||
if (pointed_object != nullptr) {
|
||||
else if (pointed_object != nullptr) {
|
||||
if (manager.isKeyPressed(sf::Keyboard::LControl)) {
|
||||
drag_start = position;
|
||||
drag_end = position;
|
||||
|
@ -63,17 +63,16 @@ bool Editor::processEvent(const sf::Event& event) {
|
|||
} else {
|
||||
select(pointed_object, SelectionMode::FLIP);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// clic gauche dans le vide : démarrage du placement en drag&drop
|
||||
drag_start = position;
|
||||
drag_end = position;
|
||||
drag_mode = DragMode::PLACE;
|
||||
else {
|
||||
drag_start = position;
|
||||
drag_end = position;
|
||||
drag_mode = DragMode::PLACE;
|
||||
|
||||
select(addObject(position), SelectionMode::REPLACE);
|
||||
return true;
|
||||
select(addObject(position), SelectionMode::REPLACE);
|
||||
}
|
||||
}
|
||||
|
||||
if (event.mouseButton.button == sf::Mouse::Right) {
|
||||
|
@ -84,7 +83,6 @@ bool Editor::processEvent(const sf::Event& event) {
|
|||
drag_mode = DragMode::REMOVE;
|
||||
|
||||
removeObject(pointed_object);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,19 +96,16 @@ bool Editor::processEvent(const sf::Event& event) {
|
|||
// mode placement d'objets
|
||||
if (drag_mode == DragMode::PLACE && pointed_object == nullptr) {
|
||||
select(addObject(position), SelectionMode::ADD);
|
||||
return true;
|
||||
}
|
||||
|
||||
// mode suppression d'objets
|
||||
if (drag_mode == DragMode::REMOVE && pointed_object != nullptr) {
|
||||
removeObject(pointed_object);
|
||||
return true;
|
||||
}
|
||||
|
||||
// mode sélection libre : on l'objet à la sélection
|
||||
if (drag_mode == DragMode::SELECT_BULK) {
|
||||
select(position, SelectionMode::ADD);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,7 +119,6 @@ bool Editor::processEvent(const sf::Event& event) {
|
|||
}
|
||||
|
||||
drag_mode = DragMode::NONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// gestion des touches
|
||||
|
@ -139,13 +133,20 @@ bool Editor::processEvent(const sf::Event& event) {
|
|||
), objects.end());
|
||||
}
|
||||
|
||||
selection.clear();
|
||||
return true;
|
||||
clearSelection();
|
||||
}
|
||||
|
||||
// appui sur Ctrl + A : sélection de tous les objets
|
||||
if (event.key.code == sf::Keyboard::A && event.key.control) {
|
||||
selectAll();
|
||||
}
|
||||
|
||||
// appui sur espace : test du niveau en cours d'édition
|
||||
if (event.key.code == sf::Keyboard::Space) {
|
||||
test();
|
||||
|
||||
// demande l'interruption du dessin de la
|
||||
// frame car l'objet risque d'être détruit
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -257,11 +258,7 @@ void Editor::select(ObjectPtr object, SelectionMode mode) {
|
|||
// pour REPLACE, on sélectionne forcément l'objet
|
||||
// pour FLIP, on le sélectionne s'il ne l'est pas, on le désélectionne sinon
|
||||
if (mode == SelectionMode::REPLACE || mode == SelectionMode::FLIP) {
|
||||
for (unsigned int i = 0; i < selection.size(); i++) {
|
||||
selection[i]->setSelected(false);
|
||||
}
|
||||
|
||||
selection.clear();
|
||||
clearSelection();
|
||||
|
||||
// on resélectionne l'objet ssi. on force la sélection
|
||||
// ou s'il n'était pas déjà sélectionné
|
||||
|
@ -291,12 +288,7 @@ void Editor::select(sf::Vector2f top_left, sf::Vector2f bottom_right) {
|
|||
std::abs(bottom_right.y - top_left.y)
|
||||
);
|
||||
|
||||
// réinitialisation de la sélectionne
|
||||
for (unsigned int i = 0; i < selection.size(); i++) {
|
||||
selection[i]->setSelected(false);
|
||||
}
|
||||
|
||||
selection.clear();
|
||||
clearSelection();
|
||||
|
||||
// sélection des éléments intersectant le rectangle
|
||||
for (unsigned int i = 0; i < objects.size(); i++) {
|
||||
|
@ -306,8 +298,26 @@ void Editor::select(sf::Vector2f top_left, sf::Vector2f bottom_right) {
|
|||
}
|
||||
}
|
||||
|
||||
void Editor::clearSelection() {
|
||||
for (unsigned int i = 0; i < selection.size(); i++) {
|
||||
selection[i]->setSelected(false);
|
||||
}
|
||||
|
||||
selection.clear();
|
||||
}
|
||||
|
||||
void Editor::selectAll() {
|
||||
std::vector<ObjectPtr>& objects = getObjects();
|
||||
|
||||
for (unsigned int i = 0; i < objects.size(); i++) {
|
||||
objects[i]->setSelected(true);
|
||||
selection.push_back(objects[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::test() {
|
||||
std::shared_ptr<Game> game = std::shared_ptr<Game>(new Game(manager));
|
||||
clearSelection();
|
||||
|
||||
// copie des propriétés
|
||||
game->setName(getName());
|
||||
|
|
38
src/game.cpp
38
src/game.cpp
|
@ -13,23 +13,15 @@ void Game::load(std::ifstream& file) {
|
|||
manager.setTitle(getName());
|
||||
}
|
||||
|
||||
void Game::frame() {
|
||||
const std::vector<sf::Event>& events = manager.getEvents();
|
||||
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
|
||||
}
|
||||
bool Game::frame() {
|
||||
// si le dessin de la frame a été interrompu par
|
||||
// le traitement événementiel, on arrête
|
||||
if (Level::frame()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
sf::Time current_time = manager.getCurrentTime();
|
||||
|
||||
if (current_time >= next_frame_time) {
|
||||
// si nous sommes en retard ou dans les temps
|
||||
// on replanifie la prochaine frame
|
||||
|
@ -47,6 +39,22 @@ void Game::frame() {
|
|||
// le temps nécessaire pour revenir dans les temps
|
||||
sf::sleep(next_frame_time - current_time);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Game::processEvent(const sf::Event& event) {
|
||||
// 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);
|
||||
|
||||
// demande l'interruption du dessin de la
|
||||
// frame car l'objet risque d'être détruit
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Game::draw() {
|
||||
|
|
|
@ -19,6 +19,7 @@ std::map<unsigned int, std::function<ObjectPtr(std::ifstream&)>> object_type_map
|
|||
|
||||
Level::Level(Manager& manager) : View(manager), total_time(30) {}
|
||||
Level::~Level() {
|
||||
setViewCenter(sf::Vector2f(0, 0));
|
||||
objects.clear();
|
||||
}
|
||||
|
||||
|
@ -28,6 +29,9 @@ void Level::load(std::ifstream& file) {
|
|||
objects.clear();
|
||||
}
|
||||
|
||||
// positionnement de la vue au centre
|
||||
setViewCenter(sf::Vector2f(0, 0));
|
||||
|
||||
// lecture de la signture du fichier ("BAR")
|
||||
char signature[3];
|
||||
file.read(signature, sizeof(signature));
|
||||
|
@ -111,6 +115,23 @@ void Level::save() {
|
|||
// TODO: faire une fonction d'enregistrement
|
||||
}
|
||||
|
||||
bool Level::frame() {
|
||||
const std::vector<sf::Event>& events = manager.getEvents();
|
||||
|
||||
// traitement des événements
|
||||
for (unsigned int i = 0; i < events.size(); i++) {
|
||||
if (processEvent(events[i])) {
|
||||
// /!\ On arrête là si on a demandé l'interruption.
|
||||
// Il est important de ne plus appeler aucune autre
|
||||
// fonction de la classe pour éviter une erreur
|
||||
// de segmentation
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Level::draw() {
|
||||
// efface la scène précédente et dessine la couche de fond
|
||||
sf::RenderWindow& window = manager.getWindow();
|
||||
|
@ -166,3 +187,11 @@ std::vector<ObjectPtr>& Level::getObjects() {
|
|||
std::vector<std::pair<float, float>>& Level::getZone() {
|
||||
return zone;
|
||||
}
|
||||
|
||||
sf::Vector2f Level::getViewCenter() {
|
||||
return manager.getWindowView().getCenter();
|
||||
}
|
||||
|
||||
void Level::setViewCenter(sf::Vector2f set_view_center) {
|
||||
manager.getWindowView().setCenter(set_view_center);
|
||||
}
|
||||
|
|
|
@ -18,13 +18,6 @@ void Manager::start() {
|
|||
return;
|
||||
}
|
||||
|
||||
// lorsque la fenêtre est redimensionnée par l'utilisateur
|
||||
if (event.type == sf::Event::Resized) {
|
||||
// mise à jour de la caméra en fonction de la taille de la fenêtre
|
||||
sf::FloatRect visibleArea(0, 0, event.size.width, event.size.height);
|
||||
setWindowView(sf::View(visibleArea));
|
||||
}
|
||||
|
||||
events.push_back(event);
|
||||
}
|
||||
|
||||
|
@ -63,11 +56,11 @@ const std::vector<sf::Event>& Manager::getEvents() {
|
|||
return events;
|
||||
}
|
||||
|
||||
sf::View Manager::getWindowView() {
|
||||
sf::View& Manager::getWindowView() {
|
||||
return window_view;
|
||||
}
|
||||
|
||||
void Manager::setWindowView(sf::View set_window_view) {
|
||||
void Manager::setWindowView(sf::View& set_window_view) {
|
||||
window.setView(set_window_view);
|
||||
window_view = set_window_view;
|
||||
}
|
||||
|
|
36
src/menu.cpp
36
src/menu.cpp
|
@ -4,7 +4,7 @@ Menu::Menu(Manager& manager) : View(manager){
|
|||
|
||||
manager.getResourceManager().setMusic("menu.wav");
|
||||
manager.getResourceManager().playMusic();
|
||||
|
||||
|
||||
menu1();
|
||||
//mise en place des propriétés des textes affichés dans le menu
|
||||
choice[0].setFont(manager.getResourceManager().getFont("Raleway-Regular.ttf"));
|
||||
|
@ -19,7 +19,7 @@ Menu::Menu(Manager& manager) : View(manager){
|
|||
}
|
||||
|
||||
//choix sélectionné à l'ouverture du menu
|
||||
selection = 0;
|
||||
selection = 0;
|
||||
}
|
||||
|
||||
Menu::~Menu(){
|
||||
|
@ -47,7 +47,7 @@ void Menu::menu2(){
|
|||
}
|
||||
|
||||
void Menu::MoveUp()
|
||||
{
|
||||
{
|
||||
//change la couleur du choix sélectionné
|
||||
if(selection-1 >= 0)
|
||||
{
|
||||
|
@ -68,15 +68,15 @@ void Menu::MoveDown()
|
|||
}
|
||||
}
|
||||
|
||||
void Menu::frame(){
|
||||
bool Menu::frame(){
|
||||
sf::RenderWindow& window = manager.getWindow();
|
||||
window.clear(sf::Color(66, 40, 245));
|
||||
|
||||
const std::vector<sf::Event>& events = manager.getEvents();
|
||||
|
||||
|
||||
for (unsigned int i = 0; i < events.size(); i++) {
|
||||
const sf::Event& event = events[i];
|
||||
|
||||
|
||||
// gestion des touches
|
||||
if (event.type == sf::Event::KeyPressed) {
|
||||
if (event.key.code == sf::Keyboard::Up) {
|
||||
|
@ -90,7 +90,7 @@ void Menu::frame(){
|
|||
//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
|
||||
//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));
|
||||
|
@ -108,11 +108,19 @@ void Menu::frame(){
|
|||
file.close();
|
||||
|
||||
manager.setView(game);
|
||||
|
||||
// demande l'interruption du dessin de la
|
||||
// frame car l'objet risque d'être détruit
|
||||
return true;
|
||||
}
|
||||
|
||||
//si on choisit "Quitter", la fenêtre se ferme
|
||||
if(selection == 3){
|
||||
manager.getWindow().close();
|
||||
|
||||
// demande l'interruption du dessin de la
|
||||
// frame car l'objet risque d'être détruit
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(menu_nb == 1){
|
||||
|
@ -122,24 +130,32 @@ void Menu::frame(){
|
|||
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);
|
||||
|
||||
// demande l'interruption du dessin de la
|
||||
// frame car l'objet risque d'être détruit
|
||||
return true;
|
||||
}
|
||||
|
||||
//si on choisit "quitter", la fenêtre se ferme
|
||||
if(selection==3){
|
||||
manager.getWindow().close();
|
||||
|
||||
// demande l'interruption du dessin de la
|
||||
// frame car l'objet risque d'être détruit
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
for(int i=0; i<NB_CHOICES; i++)
|
||||
|
@ -147,5 +163,5 @@ void Menu::frame(){
|
|||
window.draw(choice[i]);
|
||||
}
|
||||
window.display();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue