2016-04-04 18:25:56 +00:00
|
|
|
#include <cmath>
|
2016-04-05 22:31:46 +00:00
|
|
|
#include <iostream>
|
2016-04-03 20:08:11 +00:00
|
|
|
#include "editor.hpp"
|
2016-04-05 23:13:00 +00:00
|
|
|
#include "game.hpp"
|
2016-04-04 18:25:56 +00:00
|
|
|
#include "block.hpp"
|
2016-04-03 20:08:11 +00:00
|
|
|
#include "constants.hpp"
|
|
|
|
|
2016-04-05 22:31:46 +00:00
|
|
|
Editor::Editor(Manager& manager) : Level(manager),
|
2016-04-06 13:21:46 +00:00
|
|
|
widget_timer(manager, true, std::bind(&Editor::setTotalTime, this, std::placeholders::_1)) {}
|
2016-04-03 20:08:11 +00:00
|
|
|
|
|
|
|
Editor::~Editor() {}
|
|
|
|
|
2016-04-05 18:07:58 +00:00
|
|
|
void Editor::load(std::ifstream& file) {
|
|
|
|
Level::load(file);
|
2016-04-06 11:41:12 +00:00
|
|
|
manager.setTitle(sf::String(L"Édition de ") + getName());
|
2016-04-05 18:07:58 +00:00
|
|
|
}
|
|
|
|
|
2016-04-03 20:08:11 +00:00
|
|
|
void Editor::frame() {
|
2016-04-04 18:25:56 +00:00
|
|
|
const std::vector<sf::Event>& events = manager.getEvents();
|
|
|
|
|
2016-04-05 22:31:46 +00:00
|
|
|
// traitement des événements
|
2016-04-04 18:25:56 +00:00
|
|
|
for (unsigned int i = 0; i < events.size(); i++) {
|
|
|
|
const sf::Event& event = events[i];
|
|
|
|
|
2016-04-05 22:31:46 +00:00
|
|
|
// traitement des événements du widget timer
|
|
|
|
if (widget_timer.processEvent(event)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-04-04 18:25:56 +00:00
|
|
|
// lorsque l'on clique dans l'éditeur
|
|
|
|
if (event.type == sf::Event::MouseButtonPressed) {
|
|
|
|
sf::Vector2f position(event.mouseButton.x, event.mouseButton.y);
|
|
|
|
|
2016-04-05 15:50:28 +00:00
|
|
|
if (event.mouseButton.button == sf::Mouse::Left) {
|
2016-04-05 17:27:37 +00:00
|
|
|
// clic gauche : on met à jour la sélection,
|
|
|
|
// si aucune mise à jour n'est à faire, on ajoute un objet
|
|
|
|
if (!updateSelection(position)) {
|
|
|
|
addObject(position);
|
2016-04-05 15:50:28 +00:00
|
|
|
}
|
2016-04-05 22:31:46 +00:00
|
|
|
} else if (event.mouseButton.button == sf::Mouse::Right) {
|
2016-04-05 17:27:37 +00:00
|
|
|
// clic droit : on supprime l'objet pointé
|
|
|
|
removeObject(position);
|
2016-04-04 18:25:56 +00:00
|
|
|
}
|
|
|
|
}
|
2016-04-05 23:13:00 +00:00
|
|
|
|
|
|
|
// 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
|
|
|
|
}
|
|
|
|
}
|
2016-04-04 18:25:56 +00:00
|
|
|
}
|
|
|
|
|
2016-04-05 22:31:46 +00:00
|
|
|
// dessin de la frame
|
2016-04-03 20:08:11 +00:00
|
|
|
draw();
|
2016-04-06 11:25:33 +00:00
|
|
|
sf::sleep(sf::seconds(1.f / 60));
|
2016-04-03 20:08:11 +00:00
|
|
|
}
|
2016-04-05 15:50:28 +00:00
|
|
|
|
|
|
|
void Editor::draw() {
|
|
|
|
Level::draw();
|
2016-04-05 22:31:46 +00:00
|
|
|
|
2016-04-05 17:27:37 +00:00
|
|
|
sf::RenderWindow& window = manager.getWindow();
|
|
|
|
sf::View window_view = manager.getWindowView();
|
|
|
|
sf::Color selection_color(255, 50, 41);
|
|
|
|
|
2016-04-05 22:31:46 +00:00
|
|
|
// dessin de la sélection autour des objets sélectionnés
|
2016-04-05 17:27:37 +00:00
|
|
|
for (auto iter = selection.begin(); iter != selection.end(); iter++) {
|
|
|
|
sf::VertexArray selection(sf::LinesStrip, 5);
|
|
|
|
std::unique_ptr<sf::FloatRect> aabb = iter->first->getAABB();
|
|
|
|
|
|
|
|
selection[0].position = sf::Vector2f(aabb->left - .5f, aabb->top - .5f);
|
|
|
|
selection[0].color = selection_color;
|
|
|
|
selection[1].position = sf::Vector2f(aabb->left + aabb->width + .5f, aabb->top - .5f);
|
|
|
|
selection[1].color = selection_color;
|
|
|
|
selection[2].position = sf::Vector2f(aabb->left + aabb->width + .5f, aabb->top + aabb->height + .5f);
|
|
|
|
selection[2].color = selection_color;
|
|
|
|
selection[3].position = sf::Vector2f(aabb->left - .5f, aabb->top + aabb->height + .5f);
|
|
|
|
selection[3].color = selection_color;
|
|
|
|
selection[4].position = sf::Vector2f(aabb->left - .5f, aabb->top - .5f);
|
|
|
|
selection[4].color = selection_color;
|
|
|
|
|
|
|
|
window.draw(selection);
|
|
|
|
}
|
2016-04-05 15:50:28 +00:00
|
|
|
|
2016-04-05 22:31:46 +00:00
|
|
|
// dessin du widget timer
|
|
|
|
widget_timer.setTimeLeft(getTotalTime());
|
|
|
|
widget_timer.draw(sf::Vector2f(window_view.getSize().x / 2 - 50, 0));
|
|
|
|
|
2016-04-05 15:50:28 +00:00
|
|
|
// menu
|
2016-04-05 17:27:37 +00:00
|
|
|
sf::RectangleShape menu(sf::Vector2f(window_view.getSize().x, 64));
|
|
|
|
menu.setPosition(sf::Vector2f(0, window_view.getSize().y - 64));
|
|
|
|
|
|
|
|
window.draw(menu);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Editor::addObject(sf::Vector2f position) {
|
|
|
|
std::vector<ObjectPtr>& objects = getObjects();
|
|
|
|
|
|
|
|
// si demandé, on arrondit à l'unité de grille la plus proche
|
|
|
|
position /= Constants::GRID;
|
|
|
|
position.x = round(position.x);
|
|
|
|
position.y = round(position.y);
|
|
|
|
position *= Constants::GRID;
|
|
|
|
|
|
|
|
// TODO: ajouter un objet du type choisi, pas uniquement de bloc
|
2016-04-06 11:54:03 +00:00
|
|
|
ObjectPtr object = ObjectPtr(new Block);
|
2016-04-05 17:27:37 +00:00
|
|
|
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);
|
|
|
|
updateSelection(position);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Editor::removeObject(sf::Vector2f position) {
|
|
|
|
std::vector<ObjectPtr>& objects = getObjects();
|
|
|
|
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) {
|
|
|
|
selection.erase(objects[remove_object_index]);
|
|
|
|
objects.erase(objects.begin() + remove_object_index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Editor::updateSelection(sf::Vector2f position) {
|
|
|
|
std::vector<ObjectPtr>& objects = getObjects();
|
|
|
|
bool has_changed = false;
|
|
|
|
bool multi = manager.isKeyPressed(sf::Keyboard::LShift);
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < objects.size(); i++) {
|
|
|
|
if (objects[i]->getAABB()->contains(position)) {
|
|
|
|
has_changed = true;
|
|
|
|
|
|
|
|
// si l'objet n'est pas sélectionné, on le sélectionne
|
|
|
|
// sinon on le désélectionne
|
|
|
|
if (selection.count(objects[i])) {
|
|
|
|
selection.erase(objects[i]);
|
|
|
|
} else {
|
|
|
|
// avant de sélectionner le nouvel objet, on
|
|
|
|
// vide la sélection si on n'est pas en mode multi
|
|
|
|
if (!multi) {
|
|
|
|
selection.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
selection[objects[i]] = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-04-05 15:50:28 +00:00
|
|
|
|
2016-04-05 17:27:37 +00:00
|
|
|
return has_changed;
|
2016-04-05 15:50:28 +00:00
|
|
|
}
|
2016-04-05 23:13:00 +00:00
|
|
|
|
|
|
|
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());
|
2016-04-06 12:02:11 +00:00
|
|
|
game->setBackground(getBackground());
|
2016-04-05 23:13:00 +00:00
|
|
|
|
|
|
|
// copie des objets du niveau vers le jeu
|
|
|
|
std::vector<ObjectPtr>& objects = getObjects();
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < objects.size(); i++) {
|
2016-04-06 11:54:03 +00:00
|
|
|
game->getObjects().push_back(objects[i]->clone());
|
2016-04-05 23:13:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
}
|