From 183bd53b664a84e5e42f8e3566c49b86ddf34e95 Mon Sep 17 00:00:00 2001 From: zvon Date: Fri, 30 Apr 2021 23:12:53 +0200 Subject: [PATCH] Mario: saving map as binary file v1.0 --- mario/.gitignore | 1 + mario/blocks.hpp | 2 +- mario/editor.cpp | 36 +++++++++++- mario/maploader.cpp | 130 ++++++++++++++++++++++++++++++++++++-------- mario/maploader.hpp | 2 + mario/objectids.hpp | 42 +++++++------- 6 files changed, 167 insertions(+), 46 deletions(-) diff --git a/mario/.gitignore b/mario/.gitignore index fce7cdb..b0d3d15 100644 --- a/mario/.gitignore +++ b/mario/.gitignore @@ -3,3 +3,4 @@ sprites mario editor .DS_Store +*bin diff --git a/mario/blocks.hpp b/mario/blocks.hpp index 165041a..2f35056 100644 --- a/mario/blocks.hpp +++ b/mario/blocks.hpp @@ -10,7 +10,7 @@ enum BlockType { OVERWORLD = 0, UNDERWORLD = 1, WATER = 2, - BOWSER = 3 + BOWSER = 4 }; std::shared_ptr createTerrainBlock( uint64_t block_id, BlockType type, std::shared_ptr &renderer, bool collision = false ); diff --git a/mario/editor.cpp b/mario/editor.cpp index 32c6e88..e4e2ea7 100644 --- a/mario/editor.cpp +++ b/mario/editor.cpp @@ -17,6 +17,7 @@ std::shared_ptr< SDLPP::Renderer > renderer = nullptr; bool quit = false; +std::vector,16>> objects = {}; void handleKeyDown( SDL_Keycode key, SDLPP::Scene &scene ) { switch ( key ) { @@ -113,7 +114,39 @@ int main() { bg->setId( 1 ); scene->addObject( bg ); - loadMap( scene, nullptr, "testmap.txt", renderer ); + loadMap( scene, "test_binary.bin", renderer, objects ); + + // grid + for ( int i = 1; i < 20; i++ ) { + auto line_vertical = std::make_shared< SDLPP::LineRenderer >( + i * BLOCK_SIZE, 1 - 16 * BLOCK_SIZE, i * BLOCK_SIZE, 1.0, renderer, "#282828" ); + line_vertical->setStatic(); + line_vertical->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); + scene->addObject(line_vertical); + if(i > 2) { + auto line_horizontal = std::make_shared< SDLPP::LineRenderer >( + BLOCK_SIZE, ( i + 1 ) * BLOCK_SIZE, 19 * BLOCK_SIZE, + ( i + 1 ) * BLOCK_SIZE, renderer, "#282828" ); + line_horizontal->setStatic(); + line_horizontal->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); + scene->addObject(line_horizontal); + } + } + // white rectangles + 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(1); + rectangle1->addCollision(SDLPP::RectColider(0, 0, 1, 1)); + scene->addObject(rectangle1); + // white rectangles + auto rectangle2 = std::make_shared< SDLPP::RectangleRender >( + 19*BLOCK_SIZE, 4 * BLOCK_SIZE, 20*BLOCK_SIZE, 16 * BLOCK_SIZE, renderer, "#FFFFFF88", true); + rectangle2->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + rectangle2->setId(1); + rectangle2->addCollision(SDLPP::RectColider(0, 0, 1, 1)); + scene->addObject(rectangle2); + FPSmanager gFPS; SDL_initFramerate( &gFPS ); @@ -135,6 +168,7 @@ int main() { base = SDL_GetTicks(); } } +// saveMap("test_binary.bin", objects); return 0; } diff --git a/mario/maploader.cpp b/mario/maploader.cpp index 552570b..ac3ce89 100644 --- a/mario/maploader.cpp +++ b/mario/maploader.cpp @@ -5,42 +5,42 @@ #include "blocks.hpp" #include "objectids.hpp" -std::shared_ptr decodeObject( char obj, BlockType type, double x, double y, std::shared_ptr &renderer) { +uint64_t decodeObject( char obj ) { switch(obj) { case 'F': - return createTerrainBlock(FLOOR_ID, type, renderer, x, y, true); + return FLOOR_ID; case 'I': - return createTerrainBlock(HILL_INCLINE_ID, type, renderer, x, y); + return HILL_INCLINE_ID; case 'R': - return createTerrainBlock(HILL_DOTS_RIGHT_ID, type, renderer, x, y); + return HILL_DOTS_RIGHT_ID; case 'G': - return createTerrainBlock(HILL_FILL_ID, type, renderer, x, y); + return HILL_FILL_ID; case 'L': - return createTerrainBlock(HILL_DOTS_LEFT_ID, type, renderer, x, y); + return HILL_DOTS_LEFT_ID; case 'D': - return createTerrainBlock(HILL_DECLINE_ID, type, renderer, x, y); + return HILL_DECLINE_ID; case 'T': - return createTerrainBlock(HILL_TOP_ID, type, renderer, x, y); + return HILL_TOP_ID; case 'q': - return createTerrainBlock(BUSH_LEFT_ID, type, renderer, x, y); + return BUSH_LEFT_ID; case 'w': - return createTerrainBlock(BUSH_MIDDLE_ID, type, renderer, x, y); + return BUSH_MIDDLE_ID; case 'r': - return createTerrainBlock(BUSH_RIGHT_ID, type, renderer, x, y); + return BUSH_RIGHT_ID; case 'a': - return createTerrainBlock(CLOUD_LEFT_BOTTOM_ID, type, renderer, x, y); + return CLOUD_LEFT_BOTTOM_ID; case 's': - return createTerrainBlock(CLOUD_MIDDLE_BOTTOM_ID, type, renderer, x, y); + return CLOUD_MIDDLE_BOTTOM_ID; case 'd': - return createTerrainBlock(CLOUD_RIGHT_BOTTOM_ID, type, renderer, x, y); + return CLOUD_RIGHT_BOTTOM_ID; case 'z': - return createTerrainBlock(CLOUD_LEFT_TOP_ID, type, renderer, x, y); + return CLOUD_LEFT_TOP_ID; case 'x': - return createTerrainBlock(CLOUD_MIDDLE_TOP_ID, type, renderer, x, y); + return CLOUD_MIDDLE_TOP_ID; case 'c': - return createTerrainBlock(CLOUD_RIGHT_TOP_ID, type, renderer, x, y); + return CLOUD_RIGHT_TOP_ID; } - return nullptr; + return 0; } void loadMap(std::shared_ptr &scene, std::shared_ptr mario, const std::string &file, std::shared_ptr &renderer) { @@ -63,16 +63,98 @@ void loadMap(std::shared_ptr &scene, std::shared_ptr obj = nullptr; + if(id == FLOOR_ID) + obj = createTerrainBlock(id, OVERWORLD, renderer, cur_x, cur_y, true); + else + obj = createTerrainBlock(id, OVERWORLD, renderer, cur_x, cur_y); if(obj != nullptr) scene->addObject(obj); } cur_y += BLOCK_SIZE; } - if(mario != nullptr) { - mario->setPos(mario_x * BLOCK_SIZE, 1 - (rows - mario_y) * BLOCK_SIZE); - scene->moveZTop(mario); - } else { - //createMarioBlock + mario->setPos(mario_x * BLOCK_SIZE, 1 - (rows - mario_y) * BLOCK_SIZE); + scene->moveZTop(mario); +} + +/*void loadMap(std::shared_ptr &scene, const std::string &file, std::shared_ptr &renderer, std::vector,16>> &objects) { + std::fstream mapFile; + mapFile.open(file, std::ios::in); + std::string buffer; + std::getline(mapFile, buffer); + auto cols = std::stoi(buffer); + std::getline(mapFile, buffer); + auto rows = std::stoi(buffer); + std::getline(mapFile, buffer); + auto mario_x = std::stoi(buffer); + std::getline(mapFile, buffer); + auto mario_y = std::stoi(buffer); + auto cur_y = 1 - rows * BLOCK_SIZE; + objects.resize(cols); + for(int i = 0; i < rows; i++) { + std::getline(mapFile, buffer); + auto cur_x = -BLOCK_SIZE; + for(int j = 0; j < cols; j++) { + cur_x += BLOCK_SIZE; + if(buffer[j] == ' ') { + objects[j][i] = {OVERWORLD, 0}; + continue; + } + auto id = decodeObject(buffer[j]); + objects[j][i] = {OVERWORLD, id}; + + std::shared_ptr obj = nullptr; + if(id == FLOOR_ID) + obj = createTerrainBlock(id, OVERWORLD, renderer, cur_x, cur_y, true); + else + obj = createTerrainBlock(id, OVERWORLD, renderer, cur_x, cur_y); + if(obj != nullptr) + scene->addObject(obj); + } + cur_y += BLOCK_SIZE; + } + objects[mario_x][mario_y] = {OVERWORLD, MARIO_ID}; +}*/ + +void loadMap(std::shared_ptr &scene, const std::string &file, std::shared_ptr &renderer, std::vector,16>> &objects) { + std::ifstream map_file; + map_file.open(file, std::ios::in | std::ios::binary); + uint16_t cols; + map_file.read((char*)&cols, sizeof(uint16_t)/sizeof(char)); + objects.resize(cols); + for(uint16_t i = 0; i < cols; i++) { + auto &col = objects[i]; + for(int j = 0; j < 16; j++) { + uint16_t input_number; + map_file.read((char *)&input_number, sizeof(uint16_t)/sizeof(char)); + uint8_t type = (input_number & 0xF000)>>12; + uint16_t id = (input_number & 0x0FFF) | BLOCK_PREFIX; + col[i] = {type, id}; + bool collision = false; + if(id == FLOOR_ID) { + collision = true; + } + auto obj = createTerrainBlock(id, static_cast(type), renderer, i * BLOCK_SIZE, 1 - (16-j) * BLOCK_SIZE, collision); + if(obj != nullptr) + scene->addObject(obj); + } } } + +void saveMap(const std::string &file, std::vector,16>> &objects) { + std::ofstream output_file; + output_file.open(file, std::ios::out | std::ios::binary); + uint16_t cols = objects.size(); + output_file.write((char*)&cols, sizeof(uint16_t)/sizeof(char)); + for(auto &col : objects) { + for(int i = 0; i < 16; i++) { + auto &obj = col[i]; + uint16_t wide_type = obj.first; + wide_type = wide_type<<12; + uint16_t write_num = (0x0FFF & obj.second) | wide_type; + output_file.write((char*)&write_num, sizeof(uint16_t)/sizeof(char)); + } + } + output_file.close(); +} diff --git a/mario/maploader.hpp b/mario/maploader.hpp index 5e6821e..e443e7a 100644 --- a/mario/maploader.hpp +++ b/mario/maploader.hpp @@ -5,5 +5,7 @@ #include "../sdlpp/sdlpp_rectrenderer.hpp" void loadMap(std::shared_ptr &scene, std::shared_ptr mario, const std::string &file, std::shared_ptr &renderer); +void loadMap(std::shared_ptr &scene, const std::string &file, std::shared_ptr &renderer, std::vector,16>> &objects); +void saveMap(const std::string &file, std::vector,16>> &objects); #endif diff --git a/mario/objectids.hpp b/mario/objectids.hpp index 1810f52..d6354aa 100644 --- a/mario/objectids.hpp +++ b/mario/objectids.hpp @@ -1,28 +1,30 @@ #ifndef OBJECTIDS_H #define OBJECTIDS_H -#define FLOOR_ID 0x70000001 -#define HILL_INCLINE_ID 0x70000002 -#define HILL_DECLINE_ID 0x70000003 -#define HILL_DOTS_RIGHT_ID 0x70000004 -#define HILL_DOTS_LEFT_ID 0x70000005 -#define HILL_FILL_ID 0x70000006 -#define HILL_TOP_ID 0x70000007 -#define BUSH_LEFT_ID 0x70000008 -#define BUSH_MIDDLE_ID 0x70000009 -#define BUSH_RIGHT_ID 0x7000000A -#define CLOUD_LEFT_BOTTOM_ID 0x7000000B -#define CLOUD_MIDDLE_BOTTOM_ID 0x7000000C -#define CLOUD_RIGHT_BOTTOM_ID 0x7000000D -#define CLOUD_LEFT_TOP_ID 0x7000000E -#define CLOUD_MIDDLE_TOP_ID 0x7000000F -#define CLOUD_RIGHT_TOP_ID 0x70000010 +#define BLOCK_PREFIX 0x7000 +#define FLOOR_ID 0x7001 +#define HILL_INCLINE_ID 0x7002 +#define HILL_DECLINE_ID 0x7003 +#define HILL_DOTS_RIGHT_ID 0x7004 +#define HILL_DOTS_LEFT_ID 0x7005 +#define HILL_FILL_ID 0x7006 +#define HILL_TOP_ID 0x7007 +#define BUSH_LEFT_ID 0x7008 +#define BUSH_MIDDLE_ID 0x7009 +#define BUSH_RIGHT_ID 0x700A +#define CLOUD_LEFT_BOTTOM_ID 0x700B +#define CLOUD_MIDDLE_BOTTOM_ID 0x700C +#define CLOUD_RIGHT_BOTTOM_ID 0x700D +#define CLOUD_LEFT_TOP_ID 0x700E +#define CLOUD_MIDDLE_TOP_ID 0x700F +#define CLOUD_RIGHT_TOP_ID 0x7010 +#define MARIO_ID 0x7FFF -#define DEATH_ID 0x10000001 +#define DEATH_ID 0x1001 #define STOP_MOVEMENT 0x2000 -#define MARIO_FLOOR_DETECT 0x20000001 -#define MARIO_LEFT_SIDE_DETECT 0x20000002 -#define MARIO_RIGHT_SIDE_DETECT 0x20000003 +#define MARIO_FLOOR_DETECT 0x2001 +#define MARIO_LEFT_SIDE_DETECT 0x2002 +#define MARIO_RIGHT_SIDE_DETECT 0x2003 #endif