Gestion de la sélection, validation du dessin dans le manager
This commit is contained in:
parent
b11684b906
commit
83e644a0e8
|
@ -8,6 +8,16 @@
|
||||||
* niveaux du jeu
|
* niveaux du jeu
|
||||||
*/
|
*/
|
||||||
class Editor : public Level {
|
class Editor : public Level {
|
||||||
|
private:
|
||||||
|
ObjectPtr selected_object;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Dessine tous les objets, le fond et
|
||||||
|
* l'interface de l'éditeur
|
||||||
|
*/
|
||||||
|
virtual void draw();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Editor(Manager& manager);
|
Editor(Manager& manager);
|
||||||
virtual ~Editor();
|
virtual ~Editor();
|
||||||
|
|
|
@ -25,7 +25,7 @@ protected:
|
||||||
/**
|
/**
|
||||||
* Dessine tous les objets et le fond à l'écran
|
* Dessine tous les objets et le fond à l'écran
|
||||||
*/
|
*/
|
||||||
void draw();
|
virtual void draw();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Level(Manager& manager);
|
Level(Manager& manager);
|
||||||
|
|
|
@ -13,6 +13,7 @@ class Manager {
|
||||||
private:
|
private:
|
||||||
sf::RenderWindow window;
|
sf::RenderWindow window;
|
||||||
sf::Clock clock;
|
sf::Clock clock;
|
||||||
|
sf::View window_view;
|
||||||
|
|
||||||
ResourceManager resource_manager;
|
ResourceManager resource_manager;
|
||||||
std::vector<sf::Event> events;
|
std::vector<sf::Event> events;
|
||||||
|
@ -53,6 +54,16 @@ public:
|
||||||
*/
|
*/
|
||||||
const std::vector<sf::Event>& getEvents();
|
const std::vector<sf::Event>& getEvents();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renvoie la vue de la fenêtre (position centrale, taille)
|
||||||
|
*/
|
||||||
|
sf::View getWindowView();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifie la vue de la fenêtre
|
||||||
|
*/
|
||||||
|
void setWindowView(sf::View set_window_view);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renvoie un booléen attestant de l'appui sur la
|
* Renvoie un booléen attestant de l'appui sur la
|
||||||
* touche donnée ou non
|
* touche donnée ou non
|
||||||
|
|
|
@ -18,6 +18,9 @@ private:
|
||||||
|
|
||||||
mutable float inv_mass;
|
mutable float inv_mass;
|
||||||
|
|
||||||
|
sf::Sprite selection_sprite;
|
||||||
|
bool is_selected;
|
||||||
|
|
||||||
float mass;
|
float mass;
|
||||||
float charge;
|
float charge;
|
||||||
float restitution;
|
float restitution;
|
||||||
|
@ -192,6 +195,16 @@ public:
|
||||||
* Modifie la couche d'affichage de l'objet
|
* Modifie la couche d'affichage de l'objet
|
||||||
*/
|
*/
|
||||||
void setLayer(int set_layer);
|
void setLayer(int set_layer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère si l'objet est actuellement sélectionné
|
||||||
|
*/
|
||||||
|
bool isSelected() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sélectionne ou désélectionne l'objet
|
||||||
|
*/
|
||||||
|
void setSelected(bool set_selected);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 301 B |
107
src/editor.cpp
107
src/editor.cpp
|
@ -1,9 +1,10 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
#include "editor.hpp"
|
#include "editor.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), selected_object(nullptr) {
|
||||||
// activation de la synchronisation verticale
|
// activation de la synchronisation verticale
|
||||||
// car, dans l'éditeur, nous n'avons besoin que de dessiner
|
// car, dans l'éditeur, nous n'avons besoin que de dessiner
|
||||||
// (pas de mise à jour physique)
|
// (pas de mise à jour physique)
|
||||||
|
@ -22,40 +23,76 @@ void Editor::frame() {
|
||||||
// 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);
|
||||||
int remove_object_index = -1;
|
bool selection_changed = false;
|
||||||
|
|
||||||
// recherche d'un objet intersectant la position cliquée
|
|
||||||
for (unsigned int i = 0; i < objects.size(); i++) {
|
|
||||||
if (objects[i]->getAABB()->contains(position)) {
|
|
||||||
remove_object_index = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remove_object_index >= 0) {
|
|
||||||
// si un objet a été cliqué, on le supprime
|
|
||||||
objects.erase(objects.begin() + remove_object_index);
|
|
||||||
} else {
|
|
||||||
// sinon on crée un nouvel objet à la position cliquée
|
|
||||||
position /= Constants::GRID;
|
|
||||||
position.x = round(position.x);
|
|
||||||
position.y = round(position.y);
|
|
||||||
position *= Constants::GRID;
|
|
||||||
|
|
||||||
std::shared_ptr<Object> object = std::shared_ptr<Object>(new Block);
|
|
||||||
object->setPosition(position);
|
|
||||||
|
|
||||||
// avant d'ajouter l'objet, on vérifie qu'il ne soit
|
|
||||||
// pas superposé à un autre
|
|
||||||
float overlaps = false;
|
|
||||||
|
|
||||||
|
if (event.mouseButton.button == sf::Mouse::Left) {
|
||||||
|
// recherche d'un objet intersectant la position cliquée
|
||||||
|
// et le sélectionne si c'est le cas
|
||||||
for (unsigned int i = 0; i < objects.size(); i++) {
|
for (unsigned int i = 0; i < objects.size(); i++) {
|
||||||
if (objects[i]->getAABB()->intersects(*object->getAABB())) {
|
if (objects[i]->getAABB()->contains(position)) {
|
||||||
overlaps = true;
|
selection_changed = true;
|
||||||
|
|
||||||
|
// si l'objet n'est pas sélectionné, on le sélectionne
|
||||||
|
// sinon on le désélectionne
|
||||||
|
if (objects[i]->isSelected()) {
|
||||||
|
objects[i]->setSelected(false);
|
||||||
|
selected_object = nullptr;
|
||||||
|
} else {
|
||||||
|
// désélection du précédent objet (si applicable)
|
||||||
|
if (selected_object != nullptr) {
|
||||||
|
selected_object->setSelected(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
selected_object = objects[i];
|
||||||
|
objects[i]->setSelected(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!overlaps) {
|
// si aucune opération de sélection, on
|
||||||
objects.push_back(object);
|
// crée un nouvel objet à la position cliquée
|
||||||
|
if (!selection_changed) {
|
||||||
|
// on désélectionne tout objet sélectionné
|
||||||
|
if (selected_object != nullptr) {
|
||||||
|
selected_object->setSelected(false);
|
||||||
|
selected_object = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
position /= Constants::GRID;
|
||||||
|
position.x = round(position.x);
|
||||||
|
position.y = round(position.y);
|
||||||
|
position *= Constants::GRID;
|
||||||
|
|
||||||
|
std::shared_ptr<Object> object = std::shared_ptr<Object>(new Block);
|
||||||
|
object->setPosition(position);
|
||||||
|
|
||||||
|
// avant d'ajouter l'objet, on vérifie qu'il ne soit
|
||||||
|
// pas superposé à un autre
|
||||||
|
float overlaps = false;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < objects.size(); i++) {
|
||||||
|
if (objects[i]->getAABB()->intersects(*object->getAABB())) {
|
||||||
|
overlaps = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!overlaps) {
|
||||||
|
objects.push_back(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.mouseButton.button == sf::Mouse::Right) {
|
||||||
|
int remove_object_index = -1;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < objects.size(); i++) {
|
||||||
|
if (objects[i]->getAABB()->contains(position)) {
|
||||||
|
remove_object_index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove_object_index >= 0) {
|
||||||
|
objects.erase(objects.begin() + remove_object_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,3 +100,13 @@ void Editor::frame() {
|
||||||
|
|
||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Editor::draw() {
|
||||||
|
Level::draw();
|
||||||
|
|
||||||
|
// menu
|
||||||
|
sf::RectangleShape menu(sf::Vector2f(manager.getWindowView().getSize().x, 64));
|
||||||
|
menu.setPosition(sf::Vector2f(0, manager.getWindowView().getSize().y - 64));
|
||||||
|
|
||||||
|
manager.getWindow().draw(menu);
|
||||||
|
}
|
||||||
|
|
|
@ -123,8 +123,6 @@ void Level::draw() {
|
||||||
display_queue.top()->draw(manager);
|
display_queue.top()->draw(manager);
|
||||||
display_queue.pop();
|
display_queue.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
window.display();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Level::getName() {
|
std::string Level::getName() {
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
Manager::Manager() : window(
|
Manager::Manager() : window(
|
||||||
sf::VideoMode(704, 480), "Projet CMI", sf::Style::Default,
|
sf::VideoMode(704, 480), "Projet CMI", sf::Style::Default,
|
||||||
sf::ContextSettings(0, 0, 2)
|
sf::ContextSettings(0, 0, 2)
|
||||||
), view(NULL) {}
|
), view(NULL) {
|
||||||
|
window_view = window.getView();
|
||||||
|
}
|
||||||
|
|
||||||
void Manager::start() {
|
void Manager::start() {
|
||||||
while (window.isOpen()) {
|
while (window.isOpen()) {
|
||||||
|
@ -22,7 +24,7 @@ void Manager::start() {
|
||||||
if (event.type == sf::Event::Resized) {
|
if (event.type == sf::Event::Resized) {
|
||||||
// mise à jour de la caméra en fonction de la taille de la fenêtre
|
// 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);
|
sf::FloatRect visibleArea(0, 0, event.size.width, event.size.height);
|
||||||
window.setView(sf::View(visibleArea));
|
setWindowView(sf::View(visibleArea));
|
||||||
}
|
}
|
||||||
|
|
||||||
events.push_back(event);
|
events.push_back(event);
|
||||||
|
@ -35,6 +37,7 @@ void Manager::start() {
|
||||||
}
|
}
|
||||||
|
|
||||||
view->frame();
|
view->frame();
|
||||||
|
window.display();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +61,15 @@ const std::vector<sf::Event>& Manager::getEvents() {
|
||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sf::View Manager::getWindowView() {
|
||||||
|
return window_view;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::setWindowView(sf::View set_window_view) {
|
||||||
|
window.setView(set_window_view);
|
||||||
|
window_view = set_window_view;
|
||||||
|
}
|
||||||
|
|
||||||
bool Manager::isKeyPressed(sf::Keyboard::Key key) const {
|
bool Manager::isKeyPressed(sf::Keyboard::Key key) const {
|
||||||
return sf::Keyboard::isKeyPressed(key) && window.hasFocus();
|
return sf::Keyboard::isKeyPressed(key) && window.hasFocus();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ const unsigned int Object::PROP_LAYER = 6;
|
||||||
|
|
||||||
Object::Object() :
|
Object::Object() :
|
||||||
acceleration(0, 0), velocity(0, 0), position(0, 0),
|
acceleration(0, 0), velocity(0, 0), position(0, 0),
|
||||||
inv_mass(-1.f),
|
inv_mass(-1.f), is_selected(false),
|
||||||
|
|
||||||
// valeurs par défaut pour les propriétés
|
// valeurs par défaut pour les propriétés
|
||||||
// de tous les objets du jeu
|
// de tous les objets du jeu
|
||||||
|
@ -129,7 +129,16 @@ sf::Vector2f Object::getForces(
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::draw(Manager& manager) {
|
void Object::draw(Manager& manager) {
|
||||||
|
// si l'objet est sélectionné, dessin de la texture de sélection
|
||||||
|
if (isSelected()) {
|
||||||
|
selection_sprite.setOrigin(sf::Vector2f(22, 22));
|
||||||
|
selection_sprite.setPosition(getPosition());
|
||||||
|
selection_sprite.setTexture(
|
||||||
|
manager.getResourceManager().getTexture("selection.png")
|
||||||
|
);
|
||||||
|
|
||||||
|
manager.getWindow().draw(selection_sprite);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::updateVelocity(
|
void Object::updateVelocity(
|
||||||
|
@ -317,6 +326,25 @@ void Object::setLayer(int set_layer) {
|
||||||
layer = set_layer;
|
layer = set_layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Object::isSelected() const {
|
||||||
|
return is_selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::setSelected(bool set_selected) {
|
||||||
|
is_selected = set_selected;
|
||||||
|
}
|
||||||
|
|
||||||
bool ObjectCompare::operator()(ObjectPtr const &t1, ObjectPtr const &t2) const {
|
bool ObjectCompare::operator()(ObjectPtr const &t1, ObjectPtr const &t2) const {
|
||||||
|
// détermine la priorité de dessin des objets
|
||||||
|
// - si un objet est sélectionné, il est prioritaire
|
||||||
|
// - sinon, l'objet de la plus haute couche est prioritaire
|
||||||
|
if (t1->isSelected()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t2->isSelected()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return t1->getLayer() > t2->getLayer();
|
return t1->getLayer() > t2->getLayer();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue