Mario editor: use visitors

This commit is contained in:
2021-05-02 14:14:11 +02:00
parent 34324d3054
commit 96857a99af
11 changed files with 268 additions and 100 deletions
+52 -79
View File
@@ -10,47 +10,27 @@
#endif // UNIX
#include <thread>
#include <mutex>
#include "global_vars.hpp"
#include "objectids.hpp"
#include "blocks.hpp"
#include "maploader.hpp"
#include "../sdlpp/sdlpp_mouse.hpp"
#define EDIT_SQUARE 0xF001
#define MOUSE_ID 0xF002
#define LEFT_ID 0xF003
#define RIGHT_ID 0xF004
#include "edit_box.hpp"
#include "editor_visitor.hpp"
std::shared_ptr< SDLPP::Renderer > renderer = nullptr;
bool quit = false;
std::vector<std::array<std::tuple<uint8_t, uint16_t, uint8_t, uint8_t, uint8_t, uint8_t>,16>> objects = {};
bool update_size = false;
bool selected_left = false;
bool selected_right = false;
std::vector<std::array<std::tuple<uint8_t, uint16_t, uint8_t, uint8_t, uint8_t, uint8_t>,16>> objects = {};
uint64_t current_selected_flags = 0;
uint64_t previous_selected_flags = 0;
std::mutex destruction_mutex;
int current_start_index = 0;
int current_max_index = 0;
std::pair<int, int> current_box = {0, 0};
std::pair<int, int> backup_box = {0, 0};
std::shared_ptr<SDLPP::RenderObject> placeholderGround = nullptr;
class EditBox : public SDLPP::RectangleRender {
public:
EditBox(int x, int y, std::shared_ptr<SDLPP::Renderer> renderer) : SDLPP::RectangleRender(BLOCK_SIZE + x*BLOCK_SIZE, 4*BLOCK_SIZE + y*BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, renderer) {
_x = x;
_y = y;
setId(EDIT_SQUARE);
setColiderColor("#FF00AA");
setPermanent();
setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
addCollision(SDLPP::RectColider(0,0,1,1));
}
std::pair<int, int> getIndexes() {
return {_x, _y};
}
private:
int _x;
int _y;
};
SDLPP::Vec2D<int> current_box = {0, 0};
std::shared_ptr<SDLPP::RenderObject> current_tool = nullptr;
void handleKeyDown( SDL_Keycode key, SDLPP::Scene &scene ) {
switch ( key ) {
@@ -107,59 +87,48 @@ void pollEvents( SDLPP::Scene &scene ) {
}
break;
case SDL_MOUSEMOTION: {
auto mouse = scene.getObjects({MOUSE_ID})[0];
auto mouse = scene.getObjects({EDITOR_MOUSE_ID})[0];
mouse->setPos(SDLPP::Mouse::getMousePositionDouble(scene.getRenderer(), SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER));
auto collisions = scene.getCollisions(*mouse);
selected_left = false;
selected_right = false;
current_box = {-1, -1};
if(collisions.size() >= 2) {
for(auto &collision : collisions) {
if(collision.second->getId() == EDIT_SQUARE) {
current_box = dynamic_cast<EditBox&>(*collision.second).getIndexes();
placeholderGround->setPos(BLOCK_SIZE + current_box.first * BLOCK_SIZE, 4*BLOCK_SIZE + current_box.second * BLOCK_SIZE);
} else if (collision.second->getId() == LEFT_ID) {
selected_left = true;
} else if (collision.second->getId() == RIGHT_ID) {
selected_right = true;
}
}
MouseVisitor visitor;
scene.visitCollisions(*mouse, visitor);
current_selected_flags = visitor.getFlags();
current_box = visitor.getEditBoxIndexes();
if(visitor.foundEditBox()) {
current_tool->setPos(BLOCK_SIZE + current_box.getX() * BLOCK_SIZE, 4*BLOCK_SIZE + current_box.getY() * BLOCK_SIZE);
}
}
break;
case SDL_MOUSEBUTTONUP:
if(selected_left && current_start_index != 0) {
if(previous_selected_flags == current_selected_flags && MouseVisitor::moveMapLeft(current_selected_flags) && current_start_index != 0) {
current_start_index -= 1;
scene.moveEverything(BLOCK_SIZE, 0);
}
if(selected_right && current_start_index != current_max_index) {
if(previous_selected_flags == current_selected_flags && MouseVisitor::moveMapRight(current_selected_flags) && current_start_index != current_max_index) {
current_start_index += 1;
scene.moveEverything(-BLOCK_SIZE,0);
}
if(current_box == backup_box && current_box.first != -1) {
auto mouse = scene.getObjects({MOUSE_ID})[0];
mouse->setPos(SDLPP::Mouse::getMousePositionDouble(scene.getRenderer(), SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER));
auto collisions = scene.getCollisions(*mouse);
std::cout << "BOUT TO" << std::endl;
bool deleted = false;
for(auto &collision : collisions) {
if(collision.second->getId() == FLOOR_ID) {
std::cout << "DELETING" << std::endl;
collision.second->destroy();
objects[current_start_index + current_box.first][current_box.second] = {OVERWORLD, 0, 0, 0, 0, 0};
deleted = true;
break;
}
if(current_box.getX() != -1) {
std::lock_guard<std::mutex> lock(destruction_mutex);
ToolVisitor visitor;
visitor.setVisitorType(TOOL_VISITOR_TYPE);
scene.visitCollisions(*current_tool, visitor);
if(visitor.removeBlock()) {
// TODO check if modifier
objects[current_start_index + current_box.getX()][current_box.getY()] = {OVERWORLD, 0, 0, 0, 0, 0};
}
if(visitor.addBlock()) {
// TODO check if modifier
objects[current_start_index + current_box.getX()][current_box.getY()] = {OVERWORLD, current_tool->getId(), 0, 0, 0, 0};
auto obj = createTerrainBlock(current_tool->getId(), OVERWORLD, renderer, 1 + current_box.getX(), current_box.getY(), true);
obj->getCollisions()[0]->setId(EDITOR_TERRAIN_ID);
scene.addObject(obj);
scene.setZIndex(obj, 1);
}
if(deleted)
break;
std::cout << "ADDING" << std::endl;
objects[current_start_index + current_box.first][current_box.second] = {OVERWORLD, FLOOR_ID, 0, 0, 0, 0};
scene.addObject(createTerrainBlock(FLOOR_ID, OVERWORLD, renderer, BLOCK_SIZE + current_box.first * BLOCK_SIZE, 4*BLOCK_SIZE + current_box.second * BLOCK_SIZE, true));
}
break;
case SDL_MOUSEBUTTONDOWN:
backup_box = current_box;
previous_selected_flags = current_selected_flags;
break;
default:
break;
@@ -227,7 +196,7 @@ int main() {
auto rectangle1 = std::make_shared< SDLPP::RectangleRender >(
0, 4 * BLOCK_SIZE, BLOCK_SIZE, 16 * BLOCK_SIZE, renderer, "#FFFFFF88", true);
rectangle1->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
rectangle1->setId(LEFT_ID);
rectangle1->setId(EDITOR_LEFT_MAP_ID);
rectangle1->setPermanent();
rectangle1->addCollision(SDLPP::RectColider(0, 0, 1, 1));
scene->addObject(rectangle1);
@@ -235,7 +204,7 @@ int main() {
auto rectangle2 = std::make_shared< SDLPP::RectangleRender >(
19*BLOCK_SIZE, 4 * BLOCK_SIZE, BLOCK_SIZE, 16 * BLOCK_SIZE, renderer, "#FFFFFF88", true);
rectangle2->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
rectangle2->setId(RIGHT_ID);
rectangle2->setId(EDITOR_RIGHT_MAP_ID);
rectangle2->setPermanent();
rectangle2->addCollision(SDLPP::RectColider(0, 0, 1, 1));
scene->addObject(rectangle2);
@@ -245,13 +214,13 @@ int main() {
font, "#000000", "#282828", 0.05 );
auto left = std::make_shared< SDLPP::TextRenderer >(
0, 11.5 * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, renderer, "<", font_config);
left->setId(LEFT_ID);
left->setId(0);
left->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
left->setPermanent();
scene->addObject(left);
auto right = std::make_shared< SDLPP::TextRenderer >(
19*BLOCK_SIZE, 11.5 * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, renderer, ">", font_config);
right->setId(RIGHT_ID);
right->setId(0);
right->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
right->setPermanent();
scene->addObject(right);
@@ -263,9 +232,11 @@ int main() {
}
auto mouse =
std::make_shared< SDLPP::RectangleRender >( 0.01, 0.01, 0.01, 0.01, renderer );
std::make_shared< SDLPP::RectangleRender >( 0.01, 0.01, 0, 0, renderer );
mouse->setMinWidth(1);
mouse->setMinHeight(1);
mouse->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER );
mouse->setId( MOUSE_ID );
mouse->setId( EDITOR_MOUSE_ID );
mouse->setColiderColor("#00FF00");
mouse->addCollision(
SDLPP::RectColider( { 0, 0 }, { 1, 1 } ) );
@@ -274,11 +245,12 @@ int main() {
auto placeholder_texture = std::make_shared< SDLPP::Texture >(
renderer, "sprites/terrain.png", MARIO_OVERWORLD_COLORKEY );
placeholderGround = createTerrainBlock(FLOOR_ID, OVERWORLD, renderer, placeholder_texture, true);
placeholderGround->setTextureAlpha(100);
placeholderGround->setId(0);
scene->addObject(placeholderGround);
scene->moveZTop(placeholderGround);
current_tool = createTerrainBlock(FLOOR_ID, OVERWORLD, renderer, placeholder_texture, false);
current_tool->addCollision(SDLPP::RectColider(0.1, 0.1, 0.8, 0.8));
current_tool->setTextureAlpha(100);
dynamic_cast<MarioBlock&>(*current_tool).setTool();
scene->addObject(current_tool);
scene->moveZTop(current_tool);
scene->moveEverything(BLOCK_SIZE, 0);
FPSmanager gFPS;
@@ -292,6 +264,7 @@ int main() {
while ( !quit ) {
SDL_PumpEvents();
SDL_framerateDelay( &gFPS );
std::lock_guard<std::mutex> lock(destruction_mutex);
scene->renderScene();
renderer->presentRenderer();
frames++;