Gestion améliorée de la caméra

This commit is contained in:
Mattéo Delabre 2016-04-08 02:21:19 +02:00
parent c560073c5f
commit 266c0529d9
6 changed files with 116 additions and 52 deletions

View File

@ -15,8 +15,8 @@ enum class SelectionMode {REPLACE, FLIP, ADD};
class Editor : public Level { class Editor : public Level {
private: private:
std::vector<ObjectPtr> selection; std::vector<ObjectPtr> selection;
sf::Vector2f drag_start; sf::Vector2i drag_start;
sf::Vector2f drag_end; sf::Vector2i drag_end;
DragMode drag_mode; DragMode drag_mode;
WidgetTimer widget_timer; WidgetTimer widget_timer;

View File

@ -15,6 +15,7 @@
*/ */
class Level : public View { class Level : public View {
private: private:
sf::View camera;
sf::String name; sf::String name;
int total_time; int total_time;
sf::Sprite background; sf::Sprite background;
@ -32,7 +33,13 @@ protected:
* Traite un événement et renvoie true si le * Traite un événement et renvoie true si le
* dessin de la frame doit être interrompu * dessin de la frame doit être interrompu
*/ */
virtual bool processEvent(const sf::Event& event) = 0; virtual bool processEvent(const sf::Event& event);
/**
* Convertit les coordonnées à l'écran en coordonnées du monde
* d'après la vue caméra
*/
sf::Vector2f convertCoords(sf::Vector2i initial);
public: public:
Level(Manager& manager); Level(Manager& manager);
@ -95,14 +102,14 @@ public:
std::vector<std::pair<float, float>>& getZone(); std::vector<std::pair<float, float>>& getZone();
/** /**
* Récupère le centre de la vue * Récupère la caméra actuelle
*/ */
sf::Vector2f getViewCenter(); sf::View getCamera();
/** /**
* Modifie le centre de la vue * Modifie la caméra
*/ */
void setViewCenter(sf::Vector2f set_view_center); void setCamera(sf::View set_camera);
}; };
#endif #endif

View File

@ -15,6 +15,7 @@ private:
sf::Clock clock; sf::Clock clock;
sf::View window_view; sf::View window_view;
sf::String title; sf::String title;
sf::View default_view;
ResourceManager resource_manager; ResourceManager resource_manager;
std::vector<sf::Event> events; std::vector<sf::Event> events;
@ -61,14 +62,9 @@ public:
const std::vector<sf::Event>& getEvents(); const std::vector<sf::Event>& getEvents();
/** /**
* Renvoie la vue de la fenêtre (position centrale, taille) * Remet la vue par défaut (zoom 1:1, origine en haut à gauche)
*/ */
sf::View& getWindowView(); void resetDefaultView();
/**
* Modifie la vue de la fenêtre
*/
void setWindowView(sf::View& set_window_view);
/** /**
* Renvoie le titre actuel de la fenêtre * Renvoie le titre actuel de la fenêtre

View File

@ -8,6 +8,8 @@
const sf::Color SELECTION_COLOR = sf::Color(33, 33, 33, 40); const sf::Color SELECTION_COLOR = sf::Color(33, 33, 33, 40);
const sf::Color SELECTION_BORDER_COLOR = sf::Color(33, 33, 33, 127); const sf::Color SELECTION_BORDER_COLOR = sf::Color(33, 33, 33, 127);
const int SCROLL_SPEED = 2;
const int SCROLL_PADDING = 8;
Editor::Editor(Manager& manager) : Level(manager), drag_mode(DragMode::NONE), Editor::Editor(Manager& manager) : Level(manager), drag_mode(DragMode::NONE),
widget_timer(manager, true, std::bind(&Editor::setTotalTime, this, std::placeholders::_1)) {} widget_timer(manager, true, std::bind(&Editor::setTotalTime, this, std::placeholders::_1)) {}
@ -34,6 +36,10 @@ bool Editor::frame() {
} }
bool Editor::processEvent(const sf::Event& event) { bool Editor::processEvent(const sf::Event& event) {
if (Level::processEvent(event)) {
return true;
}
// traitement des événements du widget timer // traitement des événements du widget timer
if (widget_timer.processEvent(event)) { if (widget_timer.processEvent(event)) {
return false; return false;
@ -41,22 +47,23 @@ bool Editor::processEvent(const sf::Event& event) {
// 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::Vector2i mouse_position(event.mouseButton.x, event.mouseButton.y);
sf::Vector2f position = convertCoords(mouse_position);
ObjectPtr pointed_object = getObject(position); ObjectPtr pointed_object = getObject(position);
if (event.mouseButton.button == sf::Mouse::Left) { if (event.mouseButton.button == sf::Mouse::Left) {
// clic + shift : sélection par rectangle de sélection // clic + shift : sélection par rectangle de sélection
if (manager.isKeyPressed(sf::Keyboard::LShift)) { if (manager.isKeyPressed(sf::Keyboard::LShift)) {
drag_start = position; drag_start = mouse_position;
drag_end = position; drag_end = mouse_position;
drag_mode = DragMode::SELECT_RECT; drag_mode = DragMode::SELECT_RECT;
} }
// clic sur un objet : démarrage de la sélection libre // clic sur un objet : démarrage de la sélection libre
else if (pointed_object != nullptr) { else if (pointed_object != nullptr) {
if (manager.isKeyPressed(sf::Keyboard::LControl)) { if (manager.isKeyPressed(sf::Keyboard::LControl)) {
drag_start = position; drag_start = mouse_position;
drag_end = position; drag_end = mouse_position;
drag_mode = DragMode::SELECT_BULK; drag_mode = DragMode::SELECT_BULK;
select(pointed_object, SelectionMode::ADD); select(pointed_object, SelectionMode::ADD);
@ -67,8 +74,8 @@ bool Editor::processEvent(const sf::Event& event) {
// clic gauche dans le vide : démarrage du placement en drag&drop // clic gauche dans le vide : démarrage du placement en drag&drop
else { else {
drag_start = position; drag_start = mouse_position;
drag_end = position; drag_end = mouse_position;
drag_mode = DragMode::PLACE; drag_mode = DragMode::PLACE;
select(addObject(position), SelectionMode::REPLACE); select(addObject(position), SelectionMode::REPLACE);
@ -78,8 +85,8 @@ bool Editor::processEvent(const sf::Event& event) {
if (event.mouseButton.button == sf::Mouse::Right) { if (event.mouseButton.button == sf::Mouse::Right) {
// clic droit sur un objet : démarrage de la suppression en drag&drop // clic droit sur un objet : démarrage de la suppression en drag&drop
if (pointed_object != nullptr) { if (pointed_object != nullptr) {
drag_start = position; drag_start = mouse_position;
drag_end = position; drag_end = mouse_position;
drag_mode = DragMode::REMOVE; drag_mode = DragMode::REMOVE;
removeObject(pointed_object); removeObject(pointed_object);
@ -89,9 +96,11 @@ bool Editor::processEvent(const sf::Event& event) {
// lorsqu'on déplace la souris // lorsqu'on déplace la souris
if (event.type == sf::Event::MouseMoved) { if (event.type == sf::Event::MouseMoved) {
sf::Vector2f position(event.mouseMove.x, event.mouseMove.y); sf::Vector2i mouse_position(event.mouseMove.x, event.mouseMove.y);
sf::Vector2f position = convertCoords(mouse_position);
ObjectPtr pointed_object = getObject(position); ObjectPtr pointed_object = getObject(position);
drag_end = position;
drag_end = mouse_position;
// mode placement d'objets // mode placement d'objets
if (drag_mode == DragMode::PLACE && pointed_object == nullptr) { if (drag_mode == DragMode::PLACE && pointed_object == nullptr) {
@ -111,11 +120,9 @@ bool Editor::processEvent(const sf::Event& event) {
// lorsqu'on relâche un clic dans l'éditeur // lorsqu'on relâche un clic dans l'éditeur
if (event.type == sf::Event::MouseButtonReleased) { if (event.type == sf::Event::MouseButtonReleased) {
sf::Vector2f position(event.mouseButton.x, event.mouseButton.y);
// mode sélection rectangulaire : on applique la sélection // mode sélection rectangulaire : on applique la sélection
if (drag_mode == DragMode::SELECT_RECT) { if (drag_mode == DragMode::SELECT_RECT) {
select(drag_start, drag_end); select(convertCoords(drag_start), convertCoords(drag_end));
} }
drag_mode = DragMode::NONE; drag_mode = DragMode::NONE;
@ -155,15 +162,37 @@ bool Editor::processEvent(const sf::Event& event) {
} }
void Editor::draw() { void Editor::draw() {
Level::draw();
sf::RenderWindow& window = manager.getWindow(); sf::RenderWindow& window = manager.getWindow();
sf::View window_view = manager.getWindowView(); sf::Vector2i window_size = (sf::Vector2i) window.getSize();
// scroll de la caméra lorsque la souris se situe sur les bords
if (window.hasFocus()) {
sf::View camera = getCamera();
sf::Vector2i mouse = sf::Mouse::getPosition(window);
if (mouse.x < SCROLL_PADDING) {
camera.move(sf::Vector2f(-SCROLL_SPEED, 0));
} else if (mouse.x > window_size.x - SCROLL_PADDING) {
camera.move(sf::Vector2f(SCROLL_SPEED, 0));
} else if (mouse.y < SCROLL_PADDING) {
camera.move(sf::Vector2f(0, -SCROLL_SPEED));
} else if (mouse.y > window_size.y - SCROLL_PADDING) {
camera.move(sf::Vector2f(0, SCROLL_SPEED));
}
setCamera(camera);
}
// dessin des objets du niveau
Level::draw();
// dessin du rectangle de sélection // dessin du rectangle de sélection
if (drag_mode == DragMode::SELECT_RECT) { if (drag_mode == DragMode::SELECT_RECT) {
sf::RectangleShape selection_rect(drag_end - drag_start); sf::Vector2f size = (sf::Vector2f) (drag_end - drag_start);
selection_rect.setPosition(drag_start); sf::Vector2f pos = (sf::Vector2f) drag_start;
sf::RectangleShape selection_rect(size);
selection_rect.setPosition(pos);
selection_rect.setFillColor(SELECTION_COLOR); selection_rect.setFillColor(SELECTION_COLOR);
selection_rect.setOutlineThickness(2.f); selection_rect.setOutlineThickness(2.f);
selection_rect.setOutlineColor(SELECTION_BORDER_COLOR); selection_rect.setOutlineColor(SELECTION_BORDER_COLOR);
@ -173,11 +202,11 @@ void Editor::draw() {
// dessin du widget timer // dessin du widget timer
widget_timer.setTimeLeft(getTotalTime()); widget_timer.setTimeLeft(getTotalTime());
widget_timer.draw(sf::Vector2f(window_view.getSize().x / 2 - 50, 0)); widget_timer.draw(sf::Vector2f(window_size.x / 2 - 50, 0));
// menu // menu
sf::RectangleShape menu(sf::Vector2f(window_view.getSize().x, 64)); sf::RectangleShape menu(sf::Vector2f(window_size.x, 64));
menu.setPosition(sf::Vector2f(0, window_view.getSize().y - 64)); menu.setPosition(sf::Vector2f(0, window_size.y - 64));
window.draw(menu); window.draw(menu);
} }

View File

@ -17,9 +17,12 @@ std::map<unsigned int, std::function<ObjectPtr(std::ifstream&)>> object_type_map
{Block::TYPE_ID, Block::load} {Block::TYPE_ID, Block::load}
}; };
Level::Level(Manager& manager) : View(manager), total_time(30) {} Level::Level(Manager& manager) : View(manager), total_time(30) {
camera = manager.getWindow().getDefaultView();
camera.setCenter(0, 0);
}
Level::~Level() { Level::~Level() {
setViewCenter(sf::Vector2f(0, 0));
objects.clear(); objects.clear();
} }
@ -29,8 +32,8 @@ void Level::load(std::ifstream& file) {
objects.clear(); objects.clear();
} }
// positionnement de la vue au centre // positionnement de la caméra au centre du niveau
setViewCenter(sf::Vector2f(0, 0)); camera.setCenter(0, 0);
// lecture de la signture du fichier ("BAR") // lecture de la signture du fichier ("BAR")
char signature[3]; char signature[3];
@ -132,9 +135,23 @@ bool Level::frame() {
return false; return false;
} }
bool Level::processEvent(const sf::Event& event) {
// lorsque la fenêtre est redimensionnée, mise à jour
// de la taille de la caméra
if (event.type == sf::Event::Resized) {
camera.setSize(event.size.width, event.size.height);
}
return false;
}
void Level::draw() { void Level::draw() {
// efface la scène précédente et dessine la couche de fond
sf::RenderWindow& window = manager.getWindow(); sf::RenderWindow& window = manager.getWindow();
// passage sur la vue caméra
window.setView(camera);
// efface la scène précédente et dessine la couche de fond
window.clear(sf::Color(66, 165, 245)); window.clear(sf::Color(66, 165, 245));
window.draw(background); window.draw(background);
@ -150,6 +167,9 @@ void Level::draw() {
display_queue.top()->draw(manager); display_queue.top()->draw(manager);
display_queue.pop(); display_queue.pop();
} }
// passage sur la vue par défaut
manager.resetDefaultView();
} }
sf::String Level::getName() const { sf::String Level::getName() const {
@ -188,10 +208,21 @@ std::vector<std::pair<float, float>>& Level::getZone() {
return zone; return zone;
} }
sf::Vector2f Level::getViewCenter() { sf::View Level::getCamera() {
return manager.getWindowView().getCenter(); return camera;
} }
void Level::setViewCenter(sf::Vector2f set_view_center) { sf::Vector2f Level::convertCoords(sf::Vector2i initial) {
manager.getWindowView().setCenter(set_view_center); sf::RenderWindow& window = manager.getWindow();
sf::View old_view = window.getView();
window.setView(camera);
sf::Vector2f converted = window.mapPixelToCoords(initial);
window.setView(old_view);
return converted;
}
void Level::setCamera(sf::View set_camera) {
camera = set_camera;
} }

View File

@ -18,6 +18,12 @@ void Manager::start() {
return; return;
} }
if (event.type == sf::Event::Resized) {
default_view = sf::View(sf::FloatRect(
0, 0, event.size.width, event.size.height
));
}
events.push_back(event); events.push_back(event);
} }
@ -56,13 +62,8 @@ const std::vector<sf::Event>& Manager::getEvents() {
return events; return events;
} }
sf::View& Manager::getWindowView() { void Manager::resetDefaultView() {
return window_view; window.setView(default_view);
}
void Manager::setWindowView(sf::View& set_window_view) {
window.setView(set_window_view);
window_view = set_window_view;
} }
sf::String Manager::getTitle() { sf::String Manager::getTitle() {