#include #include "ViewController.h" #include "CollisionChecker.h" #include "ControlBooleanCommand.h" #include "CycleCollisionMethodCommand.h" #include "QuadTreeCollisionChecker.h" #include "Exception.h" #include "KeyboardCode.h" #include "MouseCode.h" #include "ToggleMuseumPauseCommand.h" #include "OpenFileGUICommand.h" #include "StepTileCommand.h" #include "TimeTravelCommand.h" #include "View.h" #include "Museum.h" using namespace std; ViewController::ViewController(Museum & m, View & v) : museum(m), view(v) { } ViewController::~ViewController() { } void ViewController::update() { this->update_size(); this->update_tiles(); if (this->draw_artists) this->update_artists(); if (this->draw_pathfinding) this->update_pathfinding(); if (this->draw_quadtree) this->update_quadtree(); } void ViewController::update_size() { this->view.window_size( this->scale * this->museum.canvas.data.columns, this->scale * this->museum.canvas.data.rows ); } void ViewController::update_tiles() { for (int y = 0; y < this->museum.canvas.data.rows; y++) { for (int x = 0; x < this->museum.canvas.data.columns; x++) { Tile & tile = this->museum.canvas.get_tile({ x, y }); Rectangle rect = { .x = static_cast(x * scale), .y = static_cast(y * scale), .width = static_cast(scale - line_width), .height = static_cast(scale - line_width), }; this->view.fill_rect(rect, tile.color); } } } void ViewController::update_artists() { People & people = this->museum.people; for (Artist * artist : people.get_artists()) { Rectangle rect = { .x = static_cast(artist->data.x * scale), .y = static_cast(artist->data.y * scale), .width = static_cast(artist_size), .height = static_cast(artist_size), }; this->view.fill_rect(rect, artist->color); } } void ViewController::draw_pathfinding_dot(const XY & point, const Color & color) { this->view.fill_rect(center({ .x = static_cast(point.x * scale), .y = static_cast(point.y * scale), .width = static_cast(pathfinding_size), .height = static_cast(pathfinding_size), }), color); } void ViewController::update_pathfinding() { PathfindingContext & ctx = this->museum.pathfinding; this->draw_pathfinding_dot(ctx.get_end(), { .red = 0x00, .green = 0x00, .blue = 0xdd, }); this->draw_pathfinding_dot(ctx.get_start(), { .red = 0xff, .green = 0xff, .blue = 0xff, }); } void ViewController::update_quadtree_recursive(QuadTreeCollisionChecker * tree) { if (tree == nullptr) return; const Rectangle & tree_boundary = tree->get_boundary(); Rectangle rect = { .x = tree_boundary.x * scale, .y = tree_boundary.y * scale, .width = tree_boundary.width * scale, .height = tree_boundary.height * scale, }; this->view.draw_rect(rect, { .red = 0xff, .green = 0x00, .blue = 0xff, }, 1); this->update_quadtree_recursive(tree->subtree[0].get()); this->update_quadtree_recursive(tree->subtree[1].get()); this->update_quadtree_recursive(tree->subtree[2].get()); this->update_quadtree_recursive(tree->subtree[3].get()); } void ViewController::update_quadtree() { shared_ptr checker = this->museum.collision.get_checker(); auto tree = dynamic_cast(checker.get()); if (tree == nullptr) return; this->update_quadtree_recursive(tree); } void ViewController::ev_keydown(KeyboardCode key) { try { switch (key) { case KEY_SPACE: { ToggleMuseumPauseCommand(this->museum).execute(); break; } case KEY_ENTER: { StepTileCommand(this->museum.canvas, this->mouse_pos).execute(); break; } case KEY_O: { OpenFileGUICommand(this->museum, this->view).execute(); break; } case KEY_A: { ControlBooleanCommand(this->draw_artists).execute(); break; } case KEY_LEFT: { TimeTravelCommand(this->museum, false).execute(); break; } case KEY_RIGHT: { TimeTravelCommand(this->museum, true).execute(); break; } case KEY_C: { CycleCollisionMethodCommand(this->museum).execute(); break; } case KEY_Q: { ControlBooleanCommand(this->draw_quadtree).execute(); break; } default: break; } } catch (Exception & e) { printf("%s\n", e.what()); } } void ViewController::ev_mousedown(MouseCode button) { try { switch (button) { case MOUSE_LEFT: { this->museum.pathfinding.set_start(this->mouse_pos); break; } case MOUSE_RIGHT: { this->museum.pathfinding.set_end(this->mouse_pos); break; } default: break; } } catch (Exception & e) { printf("%s\n", e.what()); } } void ViewController::ev_mousemove(unsigned x, unsigned y) { this->mouse_pos = { .x = static_cast(x / this->scale), .y = static_cast(y / this->scale), }; } Rectangle ViewController::center(Rectangle rect) { rect.x += (scale - rect.width) / 2; rect.y += (scale - rect.height) / 2; return rect; }