diff --git a/mario/blocks.cpp b/mario/blocks.cpp index 1104aa4..6e7cb0b 100644 --- a/mario/blocks.cpp +++ b/mario/blocks.cpp @@ -1,5 +1,6 @@ #include "blocks.hpp" #include "global_vars.hpp" +#include "maploader.hpp" #include "objectids.hpp" #include "sprites.hpp" #include "editor_visitor.hpp" @@ -200,6 +201,9 @@ bool MarioBlock::hasCoin() { bool MarioBlock::hasMushroom() { return _mushroom; } +bool MarioBlock::hasTeleport() { + return !_teleport_level.empty(); +} void MarioBlock::removeCoin() { _coins--; } @@ -212,6 +216,9 @@ void MarioBlock::addMushroom() { void MarioBlock::setCoinCount(int coins) { _coins = coins; } +void MarioBlock::setTeleportLevel(const std::string &level) { + _teleport_level = level; +} void MarioBlock::setDestructible(bool destructible) { _destructible = destructible; } @@ -309,6 +316,7 @@ const std::vector possibleMods = { BACKGROUND_MODIFIER_ID, COIN_MODIFIER_ID, MUSHROOM_MODIFIER_ID, + TELEPORT_MODIFIER_ID, }; const std::vector possibleCharacters = { @@ -565,6 +573,7 @@ createBlockById(uint64_t id, int x, int y, result = std::static_pointer_cast( std::make_shared(x, y, renderer)); break; +#ifdef EDITOR case DESTRUCTIBLE_MODIFIER_ID: result = std::static_pointer_cast( std::make_shared(x, y, renderer)); @@ -573,16 +582,19 @@ createBlockById(uint64_t id, int x, int y, result = std::static_pointer_cast( std::make_shared(x, y, renderer)); break; -#ifdef EDITOR case COIN_MODIFIER_ID: result = std::static_pointer_cast( std::make_shared(x, y, renderer)); break; -#endif case MUSHROOM_MODIFIER_ID: result = std::static_pointer_cast( std::make_shared(x, y, renderer)); break; + case TELEPORT_MODIFIER_ID: + result = std::static_pointer_cast( + std::make_shared(x, y, renderer)); + break; +#endif #ifndef EDITOR case COIN_ID: result = std::static_pointer_cast( @@ -678,3 +690,7 @@ void MarioBlock::harden() { setBouncable(false); setTextureSourceRect(HARD_SRC); } + +const std::string &MarioBlock::getTeleportLevel() { + return _teleport_level; +} \ No newline at end of file diff --git a/mario/blocks.hpp b/mario/blocks.hpp index 5aca5f4..ad6c39b 100644 --- a/mario/blocks.hpp +++ b/mario/blocks.hpp @@ -32,10 +32,12 @@ public: virtual void handleVisitor(SDLPP::Visitor &visitor) {} bool hasCoin(); bool hasMushroom(); + bool hasTeleport(); void removeCoin(); void removeMushroom(); void addMushroom(); void setCoinCount(int coins); + void setTeleportLevel(const std::string &level); void setDestructible(bool destructible = true); void ensureCollision(); bool isBouncing() const; @@ -44,6 +46,7 @@ public: void checkVisibility(double rightmost_x); bool wasVisible() const; void harden(); + const std::string &getTeleportLevel(); protected: double bounce_speed = 0.5; @@ -82,6 +85,7 @@ private: bool _traveling = false; int _coins = 0; bool _mushroom = false; + std::string _teleport_level = ""; bool _release_coin = false; int ticks_to_bounce = 0; SDLPP::Vec2D og_pos = {}; diff --git a/mario/blocks/simpleblocks.cpp b/mario/blocks/simpleblocks.cpp index d062039..03564ee 100644 --- a/mario/blocks/simpleblocks.cpp +++ b/mario/blocks/simpleblocks.cpp @@ -464,3 +464,9 @@ MushroomModifierBlock::MushroomModifierBlock( : MarioBlock(x, y, renderer, g_mod_texture, MOD_MUSHROOM_SRC, false) { setId(MUSHROOM_MODIFIER_ID); } + +TeleportModifierBlock::TeleportModifierBlock( + int x, int y, std::shared_ptr &renderer) + : MarioBlock(x, y, renderer, g_mod_texture, MOD_TELEPORT_SRC, false) { + setId(MUSHROOM_MODIFIER_ID); +} diff --git a/mario/blocks/simpleblocks.hpp b/mario/blocks/simpleblocks.hpp index 26338ad..6566023 100644 --- a/mario/blocks/simpleblocks.hpp +++ b/mario/blocks/simpleblocks.hpp @@ -340,4 +340,10 @@ public: std::shared_ptr &renderer); }; +class TeleportModifierBlock : public MarioBlock { +public: + TeleportModifierBlock(int x, int y, + std::shared_ptr &renderer); +}; + #endif diff --git a/mario/main.cpp b/mario/main.cpp index cb3f3d5..e7775ee 100644 --- a/mario/main.cpp +++ b/mario/main.cpp @@ -41,6 +41,8 @@ bool __left_pressed = false; std::vector> moving_objects = {}; std::vector game_scenes{}; +std::string _teleport_level = ""; + std::mutex render_mutex; std::mutex gamescene_mutex; @@ -63,6 +65,7 @@ void handleKeyDown(SDL_Keycode key, SDLPP::Scene &scene) { break; case SDLK_s: case SDLK_DOWN: + mario->crouch(); break; case SDLK_r: scene.getRenderer().setRenderColiders( @@ -109,6 +112,17 @@ void handleKeyUp(SDL_Keycode key) { case SDLK_w: case SDLK_UP: mario->stopJump(); + break; + case SDLK_s: + case SDLK_DOWN: + mario->uncrouch(); + if(__left_pressed) { + mario->walkLeft(); + } + if(__right_pressed) { + mario->walkRight(); + } + break; default: break; } @@ -370,23 +384,49 @@ SceneStruct mainGameScene(const std::string &level_path) { return ret; } -void loadLevel(const std::string &level) { +void setTeleportLevelMain(const std::string &level) { + std::cout << "Setting: " << level << std::endl; + _teleport_level = level; +} + +void loadLevel(const std::string &level, bool reset) { // std::lock_guard lock(render_mutex); - coin_count = 0; + if(reset) { + coin_count = 0; + } std::lock_guard lock(gamescene_mutex); for (auto &scene : game_scenes) { scene.scene->resetScene(); } game_scenes.clear(); + int marioBig = 0; + if(!reset) { + if(mario->hasFire()) { + marioBig = 2; + } else if (mario->isBig()) { + marioBig = 1; + } + } game_scenes.push_back(mainGameScene("levels/" + level)); + if(!reset) { + for(int i = 0; i < marioBig; i++) { + mario->setBig(); + } + } game_scenes.back().scene->updateSizeAndPosition(); update = true; newLoaded = true; update_count = 2; - last_load_level = level; + if(reset) { + last_load_level = level; + } g_death = false; } +void loadLevel(const std::string &level) { + loadLevel(level, true); +} + void loadLastLevel() { if (last_load_level != "") { loadLevel(last_load_level); @@ -441,6 +481,10 @@ int main() { SDL_framerateDelay(&gFPS); SDL_PumpEvents(); std::lock_guard lock(render_mutex); + if (!_teleport_level.empty()) { + loadLevel(_teleport_level, false); + _teleport_level = ""; + } if (update) { for (auto &scene : game_scenes) { scene.scene->updateSizeAndPosition(); diff --git a/mario/maploader.cpp b/mario/maploader.cpp index 61f5ac2..f4316b9 100644 --- a/mario/maploader.cpp +++ b/mario/maploader.cpp @@ -152,6 +152,7 @@ void loadMapV01(std::shared_ptr &scene, bool removeCollisions = false; int coinCount = 0; bool mushroom = false; + std::string teleport_level = ""; if (!editor && block.getModifierId() == DESTRUCTIBLE_MODIFIER_ID) { destructible = true; } @@ -165,6 +166,9 @@ void loadMapV01(std::shared_ptr &scene, if (!editor && block.getModifierId() == MUSHROOM_MODIFIER_ID) { mushroom = true; } + if (!editor && block.getModifierId() == TELEPORT_MODIFIER_ID) { + teleport_level = "test.marmap"; + } // TODO add modifiers to createTerrainBlock if (block.getTerrainId() != 0) { auto obj = createTerrainBlock(block.getTerrainId(), @@ -175,6 +179,9 @@ void loadMapV01(std::shared_ptr &scene, if (mushroom) { obj->addMushroom(); } + if (!teleport_level.empty()) { + obj->setTeleportLevel(teleport_level); + } if (removeCollisions) { obj->removeCollisions(); } diff --git a/mario/mario.cpp b/mario/mario.cpp index 1305d4e..1b53778 100644 --- a/mario/mario.cpp +++ b/mario/mario.cpp @@ -36,7 +36,7 @@ Mario::Mario(int x, int y, const std::shared_ptr &renderer, std Mario::Mario(const std::shared_ptr &renderer, std::function&, bool)> addObject) : Mario(0, 0, renderer, addObject) {} void Mario::walkLeft() { - if (!controllable) { + if (!controllable || isCrouching()) { return; } if (on_ground) @@ -51,7 +51,7 @@ void Mario::walkLeft() { } void Mario::walkRight() { - if (!controllable) { + if (!controllable || isCrouching()) { return; } if (on_ground) @@ -71,6 +71,8 @@ void Mario::setStanding() { } } +void setTeleportLevelMain(const std::string &level); + void Mario::handleVisitor(SDLPP::Visitor &visitor) { #ifndef EDITOR // TODO - @@ -130,6 +132,11 @@ void Mario::handleVisitor(SDLPP::Visitor &visitor) { if (m_visitor.hasMushroom()) { setBig(); } + if (m_visitor.hasTeleport() && isCrouching()) { + std::cout << "TELEPORTING" << std::endl; + setTeleportLevelMain(m_visitor.getTeleportLevel()); + std::cout << "Setted" << std::endl; + } if (m_visitor.levelEnd() && controllable) { if (std::abs(getPos().getX() - m_visitor.getEndPos().getX()) < BLOCK_SIZE / 8) { @@ -140,6 +147,9 @@ void Mario::handleVisitor(SDLPP::Visitor &visitor) { if (m_visitor.isDead()) { handleDeath(); } + if (m_visitor.isInstantDead()) { + setDeath(); + } #endif } void Mario::handleDeath() { @@ -152,7 +162,7 @@ void Mario::handleDeath() { } void Mario::jump() { - if (!controllable) { + if (!controllable || isCrouching()) { return; } if (!on_ground) @@ -168,6 +178,19 @@ void Mario::jump() { pauseAnimation(); } +void Mario::crouch() { + if(walkingLeft()) { + walkRight(); + } else if(walkingRight()) { + walkLeft(); + } + _crouching = true; +} + +void Mario::uncrouch() { + _crouching = false; +} + #ifndef EDITOR void Mario::fire() { if (!hasFire()) { diff --git a/mario/mario.hpp b/mario/mario.hpp index f271948..574f7b6 100644 --- a/mario/mario.hpp +++ b/mario/mario.hpp @@ -18,6 +18,8 @@ public: void setStanding(); void handleVisitor(SDLPP::Visitor &visitor) override; void jump(); + void crouch(); + void uncrouch(); #ifndef EDITOR void fire(); void setAddObjFunc(std::function&, bool)> func); @@ -51,6 +53,15 @@ public: bool isJumping() const { return jumping; } + bool isCrouching() const { + return _crouching; + } + bool walkingLeft() const { + return getMovement().getX() < 0; + } + bool walkingRight() const { + return getMovement().getX() > 0; + } private: std::function&, bool)> _addObject; @@ -64,6 +75,7 @@ private: double jump_movement = 1.0; bool jumping = false; bool stop_jump = false; + bool _crouching = false; double max_jump = 0; double min_jump = 0; double slow_jump = 0; diff --git a/mario/objectids.hpp b/mario/objectids.hpp index e0304b8..ec1867c 100644 --- a/mario/objectids.hpp +++ b/mario/objectids.hpp @@ -69,6 +69,7 @@ #define BACKGROUND_MODIFIER_ID 0x6002 #define COIN_MODIFIER_ID 0x6003 #define MUSHROOM_MODIFIER_ID 0x6004 +#define TELEPORT_MODIFIER_ID 0x6005 // character IDs #define MARIO_ID 0x0F diff --git a/mario/scenes/editor_main.cpp b/mario/scenes/editor_main.cpp index 6ac0c0c..df277f2 100644 --- a/mario/scenes/editor_main.cpp +++ b/mario/scenes/editor_main.cpp @@ -291,7 +291,9 @@ void toolMoveUpdateButtons(Button *left, Button *right, int &cur_page, } void updateToolSelection(int prev_index, ToolType::Value type) { - unsetToolColor(); + if(global_vars.tool.type == type) { + unsetToolColor(); + } int cur_page = 0; size_t multiplier = 0; std::vector> *tool_vec = nullptr; @@ -340,60 +342,33 @@ void updateToolSelection(int prev_index, ToolType::Value type) { i++) { tool_vec->at(i)->setHidden(false); } - if (global_vars.tool.index / multiplier == static_cast(cur_page)) { + if (global_vars.tool.type == type && global_vars.tool.index / multiplier == static_cast(cur_page)) { setToolColor(); } } -void moveToolsLeft(ToolType::Value type) { - switch (type) { - case ToolType::BLOCK: - global_vars.tool.cur_page_tools--; - updateToolSelection(global_vars.tool.cur_page_tools + 1, type); - break; - case ToolType::MOD: - global_vars.tool.cur_page_mods--; - updateToolSelection(global_vars.tool.cur_page_mods + 1, type); - break; - case ToolType::CHARACTER: - global_vars.tool.cur_page_characters--; - updateToolSelection(global_vars.tool.cur_page_characters + 1, type); - default: - break; - } -} - -void moveToolsRight(ToolType::Value type) { - switch (type) { - case ToolType::BLOCK: - global_vars.tool.cur_page_tools++; - updateToolSelection(global_vars.tool.cur_page_tools - 1, type); - break; - case ToolType::MOD: - global_vars.tool.cur_page_mods++; - updateToolSelection(global_vars.tool.cur_page_mods - 1, type); - break; - case ToolType::CHARACTER: - global_vars.tool.cur_page_characters++; - updateToolSelection(global_vars.tool.cur_page_characters - 1, type); - default: - break; - } -} - void updateToolIndex(uint64_t new_index, ToolType::Value new_type) { int multiplier = 0; int *page = nullptr; switch (new_type) { case ToolType::BLOCK: + if(new_index >= global_vars.tools.size()) { + return; + } multiplier = 2 * TOOLS_WIDTH; page = &global_vars.tool.cur_page_tools; break; case ToolType::MOD: + if(new_index >= global_vars.mods.size()) { + return; + } multiplier = 2 * MOD_WIDTH; page = &global_vars.tool.cur_page_mods; break; case ToolType::CHARACTER: + if(new_index >= global_vars.characters.size()) { + return; + } multiplier = 2 * CHARACTER_WIDTH; page = &global_vars.tool.cur_page_characters; default: @@ -659,7 +634,7 @@ void moveModsLeft(void *input, Button *caller) { toolMoveLeft(caller, actual_input->other_button.get(), global_vars.tool.cur_page_mods, global_vars.tool.max_page_mods, false); - updateToolSelection(global_vars.tool.cur_page_tools + 1, ToolType::MOD); + updateToolSelection(global_vars.tool.cur_page_mods + 1, ToolType::MOD); } void moveModsRight(void *input, Button *caller) { @@ -667,7 +642,7 @@ void moveModsRight(void *input, Button *caller) { toolMoveRight(actual_input->other_button.get(), caller, global_vars.tool.cur_page_mods, global_vars.tool.max_page_mods, false); - updateToolSelection(global_vars.tool.cur_page_tools - 1, ToolType::MOD); + updateToolSelection(global_vars.tool.cur_page_mods - 1, ToolType::MOD); } void moveCharsLeft(void *input, Button *caller) { @@ -675,7 +650,7 @@ void moveCharsLeft(void *input, Button *caller) { toolMoveLeft(caller, actual_input->other_button.get(), global_vars.tool.cur_page_characters, global_vars.tool.max_page_characters, false); - updateToolSelection(global_vars.tool.cur_page_tools + 1, + updateToolSelection(global_vars.tool.cur_page_characters + 1, ToolType::CHARACTER); } @@ -684,7 +659,7 @@ void moveCharsRight(void *input, Button *caller) { toolMoveRight(actual_input->other_button.get(), caller, global_vars.tool.cur_page_characters, global_vars.tool.max_page_characters, false); - updateToolSelection(global_vars.tool.cur_page_tools - 1, + updateToolSelection(global_vars.tool.cur_page_characters - 1, ToolType::CHARACTER); } diff --git a/mario/sprites.cpp b/mario/sprites.cpp index a0c7b90..7a21935 100644 --- a/mario/sprites.cpp +++ b/mario/sprites.cpp @@ -101,6 +101,7 @@ extern const SDL_Rect MOD_DESTRUCTIBLE_SRC = { 0, 0, 16, 16 }; extern const SDL_Rect MOD_BACKGROUND_SRC = { 16, 0, 16, 16 }; extern const SDL_Rect MOD_COIN_SRC = { 32, 0, 16, 16 }; extern const SDL_Rect MOD_MUSHROOM_SRC = { 48, 0, 16, 16 }; +extern const SDL_Rect MOD_TELEPORT_SRC = { 0, 16, 16, 16 }; const SDLPP::Vec2D OVERWORLD_SHIFT = { 0, 0 }; const SDLPP::Vec2D UNDERWORLD_SHIFT = { 274, 0 }; diff --git a/mario/sprites.hpp b/mario/sprites.hpp index 262b9dc..3bd1160 100644 --- a/mario/sprites.hpp +++ b/mario/sprites.hpp @@ -103,6 +103,7 @@ extern const SDL_Rect MOD_DESTRUCTIBLE_SRC; extern const SDL_Rect MOD_BACKGROUND_SRC; extern const SDL_Rect MOD_COIN_SRC; extern const SDL_Rect MOD_MUSHROOM_SRC; +extern const SDL_Rect MOD_TELEPORT_SRC; //------------------ ENEMIES ------------------------- extern const SDL_Rect GOOMBA_DEATH_SRC; extern const std::vector GOOMBA_WALK_ANIM; diff --git a/mario/visitors/mario_visitor.cpp b/mario/visitors/mario_visitor.cpp index 5dde814..0246962 100644 --- a/mario/visitors/mario_visitor.cpp +++ b/mario/visitors/mario_visitor.cpp @@ -6,13 +6,20 @@ void MarioVisitor::visit(const SDLPP::RenderObject &obj) { auto id = obj.getId(); switch (id) { - case FLOOR_ID: - case BRICK_ID: - case BRICK_TOP_ID: case PIPE_LEFT_BOTTOM_ID: case PIPE_RIGHT_BOTTOM_ID: case PIPE_LEFT_TOP_ID: case PIPE_RIGHT_TOP_ID: + { + auto m_obj = dynamic_cast(obj); + if(m_obj.hasTeleport()) { + setTeleportLevel(m_obj.getTeleportLevel()); + } + } + // fallthrough + case FLOOR_ID: + case BRICK_ID: + case BRICK_TOP_ID: case STEP_ID: case SIDEWAY_PIPE_END_TOP_ID: case SIDEWAY_PIPE_END_BOTTOM_ID: @@ -50,7 +57,7 @@ void MarioVisitor::visit(const SDLPP::RenderObject &obj) { } break; case DEATH_ID: - _death = true; + _instant_death = true; break; case GOOMBA_ID: if (from != MARIO_FLOOR_DETECT && from != MARIO_ENEMY_DETECT) { diff --git a/mario/visitors/mario_visitor.hpp b/mario/visitors/mario_visitor.hpp index 4fa1f21..0886527 100644 --- a/mario/visitors/mario_visitor.hpp +++ b/mario/visitors/mario_visitor.hpp @@ -21,6 +21,9 @@ public: bool isDead() const { return _death; } + bool isInstantDead() const { + return _instant_death; + } bool isStopped() const { return stop; } @@ -124,6 +127,15 @@ public: bool hasStar() const { return _has_star; } + bool hasTeleport() const { + return !teleport_level.empty(); + } + const std::string &getTeleportLevel() const { + return teleport_level; + } + void setTeleportLevel(const std::string &level) { + teleport_level = level; + } private: bool onGround = false; @@ -151,6 +163,8 @@ private: bool _is_big = false; bool _has_star = false; bool _death = false; + bool _instant_death = false; + std::string teleport_level = ""; }; #endif