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 {
|
||||
private:
|
||||
std::vector<ObjectPtr> selection;
|
||||
sf::Vector2f drag_start;
|
||||
sf::Vector2f drag_end;
|
||||
sf::Vector2i drag_start;
|
||||
sf::Vector2i drag_end;
|
||||
DragMode drag_mode;
|
||||
WidgetTimer widget_timer;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
class Level : public View {
|
||||
private:
|
||||
sf::View camera;
|
||||
sf::String name;
|
||||
int total_time;
|
||||
sf::Sprite background;
|
||||
|
@ -32,7 +33,13 @@ protected:
|
|||
* Traite un événement et renvoie true si le
|
||||
* 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:
|
||||
Level(Manager& manager);
|
||||
|
@ -95,14 +102,14 @@ public:
|
|||
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
|
||||
|
|
|
@ -15,6 +15,7 @@ private:
|
|||
sf::Clock clock;
|
||||
sf::View window_view;
|
||||
sf::String title;
|
||||
sf::View default_view;
|
||||
|
||||
ResourceManager resource_manager;
|
||||
std::vector<sf::Event> events;
|
||||
|
@ -61,14 +62,9 @@ public:
|
|||
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();
|
||||
|
||||
/**
|
||||
* Modifie la vue de la fenêtre
|
||||
*/
|
||||
void setWindowView(sf::View& set_window_view);
|
||||
void resetDefaultView();
|
||||
|
||||
/**
|
||||
* 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_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),
|
||||
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) {
|
||||
if (Level::processEvent(event)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// traitement des événements du widget timer
|
||||
if (widget_timer.processEvent(event)) {
|
||||
return false;
|
||||
|
@ -41,22 +47,23 @@ bool Editor::processEvent(const sf::Event& event) {
|
|||
|
||||
// lorsque l'on clique dans l'éditeur
|
||||
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);
|
||||
|
||||
if (event.mouseButton.button == sf::Mouse::Left) {
|
||||
// clic + shift : sélection par rectangle de sélection
|
||||
if (manager.isKeyPressed(sf::Keyboard::LShift)) {
|
||||
drag_start = position;
|
||||
drag_end = position;
|
||||
drag_start = mouse_position;
|
||||
drag_end = mouse_position;
|
||||
drag_mode = DragMode::SELECT_RECT;
|
||||
}
|
||||
|
||||
// clic sur un objet : démarrage de la sélection libre
|
||||
else if (pointed_object != nullptr) {
|
||||
if (manager.isKeyPressed(sf::Keyboard::LControl)) {
|
||||
drag_start = position;
|
||||
drag_end = position;
|
||||
drag_start = mouse_position;
|
||||
drag_end = mouse_position;
|
||||
drag_mode = DragMode::SELECT_BULK;
|
||||
|
||||
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
|
||||
else {
|
||||
drag_start = position;
|
||||
drag_end = position;
|
||||
drag_start = mouse_position;
|
||||
drag_end = mouse_position;
|
||||
drag_mode = DragMode::PLACE;
|
||||
|
||||
select(addObject(position), SelectionMode::REPLACE);
|
||||
|
@ -78,8 +85,8 @@ bool Editor::processEvent(const sf::Event& event) {
|
|||
if (event.mouseButton.button == sf::Mouse::Right) {
|
||||
// clic droit sur un objet : démarrage de la suppression en drag&drop
|
||||
if (pointed_object != nullptr) {
|
||||
drag_start = position;
|
||||
drag_end = position;
|
||||
drag_start = mouse_position;
|
||||
drag_end = mouse_position;
|
||||
drag_mode = DragMode::REMOVE;
|
||||
|
||||
removeObject(pointed_object);
|
||||
|
@ -89,9 +96,11 @@ bool Editor::processEvent(const sf::Event& event) {
|
|||
|
||||
// lorsqu'on déplace la souris
|
||||
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);
|
||||
drag_end = position;
|
||||
|
||||
drag_end = mouse_position;
|
||||
|
||||
// mode placement d'objets
|
||||
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
|
||||
if (event.type == sf::Event::MouseButtonReleased) {
|
||||
sf::Vector2f position(event.mouseButton.x, event.mouseButton.y);
|
||||
|
||||
// mode sélection rectangulaire : on applique la sélection
|
||||
if (drag_mode == DragMode::SELECT_RECT) {
|
||||
select(drag_start, drag_end);
|
||||
select(convertCoords(drag_start), convertCoords(drag_end));
|
||||
}
|
||||
|
||||
drag_mode = DragMode::NONE;
|
||||
|
@ -155,15 +162,37 @@ bool Editor::processEvent(const sf::Event& event) {
|
|||
}
|
||||
|
||||
void Editor::draw() {
|
||||
Level::draw();
|
||||
|
||||
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
|
||||
if (drag_mode == DragMode::SELECT_RECT) {
|
||||
sf::RectangleShape selection_rect(drag_end - drag_start);
|
||||
selection_rect.setPosition(drag_start);
|
||||
sf::Vector2f size = (sf::Vector2f) (drag_end - 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.setOutlineThickness(2.f);
|
||||
selection_rect.setOutlineColor(SELECTION_BORDER_COLOR);
|
||||
|
@ -173,11 +202,11 @@ void Editor::draw() {
|
|||
|
||||
// dessin du widget timer
|
||||
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
|
||||
sf::RectangleShape menu(sf::Vector2f(window_view.getSize().x, 64));
|
||||
menu.setPosition(sf::Vector2f(0, window_view.getSize().y - 64));
|
||||
sf::RectangleShape menu(sf::Vector2f(window_size.x, 64));
|
||||
menu.setPosition(sf::Vector2f(0, window_size.y - 64));
|
||||
|
||||
window.draw(menu);
|
||||
}
|
||||
|
|
|
@ -17,9 +17,12 @@ std::map<unsigned int, std::function<ObjectPtr(std::ifstream&)>> object_type_map
|
|||
{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() {
|
||||
setViewCenter(sf::Vector2f(0, 0));
|
||||
objects.clear();
|
||||
}
|
||||
|
||||
|
@ -29,8 +32,8 @@ void Level::load(std::ifstream& file) {
|
|||
objects.clear();
|
||||
}
|
||||
|
||||
// positionnement de la vue au centre
|
||||
setViewCenter(sf::Vector2f(0, 0));
|
||||
// positionnement de la caméra au centre du niveau
|
||||
camera.setCenter(0, 0);
|
||||
|
||||
// lecture de la signture du fichier ("BAR")
|
||||
char signature[3];
|
||||
|
@ -132,9 +135,23 @@ bool Level::frame() {
|
|||
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() {
|
||||
// efface la scène précédente et dessine la couche de fond
|
||||
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.draw(background);
|
||||
|
||||
|
@ -150,6 +167,9 @@ void Level::draw() {
|
|||
display_queue.top()->draw(manager);
|
||||
display_queue.pop();
|
||||
}
|
||||
|
||||
// passage sur la vue par défaut
|
||||
manager.resetDefaultView();
|
||||
}
|
||||
|
||||
sf::String Level::getName() const {
|
||||
|
@ -188,10 +208,21 @@ std::vector<std::pair<float, float>>& Level::getZone() {
|
|||
return zone;
|
||||
}
|
||||
|
||||
sf::Vector2f Level::getViewCenter() {
|
||||
return manager.getWindowView().getCenter();
|
||||
sf::View Level::getCamera() {
|
||||
return camera;
|
||||
}
|
||||
|
||||
void Level::setViewCenter(sf::Vector2f set_view_center) {
|
||||
manager.getWindowView().setCenter(set_view_center);
|
||||
sf::Vector2f Level::convertCoords(sf::Vector2i initial) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (event.type == sf::Event::Resized) {
|
||||
default_view = sf::View(sf::FloatRect(
|
||||
0, 0, event.size.width, event.size.height
|
||||
));
|
||||
}
|
||||
|
||||
events.push_back(event);
|
||||
}
|
||||
|
||||
|
@ -56,13 +62,8 @@ const std::vector<sf::Event>& Manager::getEvents() {
|
|||
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;
|
||||
void Manager::resetDefaultView() {
|
||||
window.setView(default_view);
|
||||
}
|
||||
|
||||
sf::String Manager::getTitle() {
|
||||
|
|
Loading…
Reference in New Issue