Gestion améliorée de la caméra
This commit is contained in:
		
							parent
							
								
									c560073c5f
								
							
						
					
					
						commit
						266c0529d9
					
				|  | @ -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; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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() { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue