diff --git a/mario/blocks.cpp b/mario/blocks.cpp index e191f1f..76fed2b 100644 --- a/mario/blocks.cpp +++ b/mario/blocks.cpp @@ -47,7 +47,7 @@ void MarioBlock::visit(SDLPP::Visitor &visitor) { // TODO if big mario and _can_be_destroyed if (_destructible && !hasCoin()) { destroy(); - } else { + } else if (_bouncable) { BounceVisitor bv; bv.setVisitorType(VisitorType::Terrain); diff --git a/mario/blocks.hpp b/mario/blocks.hpp index 6574a56..6b791f0 100644 --- a/mario/blocks.hpp +++ b/mario/blocks.hpp @@ -64,6 +64,14 @@ protected: virtual void setWorldTypeSrc(LandType::Value world); + bool isBouncable() { + return _bouncable; + } + + void setBouncable(bool bouncable = true) { + _bouncable = bouncable; + } + private: bool _tool = false; bool _terrain = true; @@ -85,6 +93,7 @@ private: int _ticks_till_gravity = 0; double _gravity_acceleration = 1.0 / (64.0 / 7.0); bool _was_visible = false; + bool _bouncable = true; }; extern const std::vector possibleBlocks; diff --git a/mario/blocks/simpleblocks.cpp b/mario/blocks/simpleblocks.cpp index 12dc1c2..ce7bca0 100644 --- a/mario/blocks/simpleblocks.cpp +++ b/mario/blocks/simpleblocks.cpp @@ -204,6 +204,7 @@ PoleTopBlock::PoleTopBlock(int x, int y, : MarioBlock(x, y, renderer, g_terrain_texture, POLE_TOP_SRC, false) { ensureCollision(); setId(POLE_TOP_ID); + setBouncable(false); } PoleBottomBlock::PoleBottomBlock(int x, int y, @@ -212,11 +213,13 @@ PoleBottomBlock::PoleBottomBlock(int x, int y, false) { ensureCollision(); setId(POLE_BOTTOM_ID); + setBouncable(false); } FlagBlock::FlagBlock(int x, int y, std::shared_ptr &renderer) : MarioBlock(x, y, renderer, g_terrain_texture, FLAG_SRC, false) { setId(FLAG_ID); + setBouncable(false); } StepBlock::StepBlock(int x, int y, std::shared_ptr &renderer) diff --git a/mario/main.cpp b/mario/main.cpp index 7ad2877..8ccda9e 100644 --- a/mario/main.cpp +++ b/mario/main.cpp @@ -70,12 +70,11 @@ void handleKeyDown(SDL_Keycode key, SDLPP::Scene &scene) { void handleKeyUp(SDL_Keycode key) { switch (key) { - case SDLK_ESCAPE: - { - std::lock_guard lock(render_mutex); - game_scenes.push_back(createGameMainMenuScene(renderer, false, true, true)); - } - break; + case SDLK_ESCAPE: { + std::lock_guard lock(render_mutex); + game_scenes.push_back( + createGameMainMenuScene(renderer, false, true, true)); + } break; case SDLK_a: mario->walkRight(); break; @@ -147,7 +146,7 @@ void pollEvents(SDLPP::Scene &scene) { } void doInputMainGame(std::shared_ptr scene) { - if(newLoaded) { + if (newLoaded) { auto prev_mario_pos = mario->getAbsolutePos(); scene->updateSizeAndPosition(); moveToMarioPosition(*scene, prev_mario_pos); @@ -155,8 +154,9 @@ void doInputMainGame(std::shared_ptr scene) { update_count = 2; newLoaded = false; } - if(g_death) { - game_scenes.push_back(createGameMainMenuScene(renderer, true, false, true)); + if (g_death) { + game_scenes.push_back( + createGameMainMenuScene(renderer, true, false, true)); g_death = false; } pollEvents(*scene); @@ -170,12 +170,11 @@ void doInputMainGame(std::shared_ptr scene) { continue; } auto visitor = getVisitor(*moving_objects[i], *scene, g_death, - coin_count, moving_objects); + coin_count, moving_objects); scene->visitCollisions(*moving_objects[i], *visitor); moving_objects[i]->handleVisitor(*visitor); - auto rightmost_pos = - moving_objects[i]->getAbsolutePos().getX() + - moving_objects[i]->getDoubleRect().second.getX(); + auto rightmost_pos = moving_objects[i]->getAbsolutePos().getX() + + moving_objects[i]->getDoubleRect().second.getX(); if (rightmost_pos < 0 && moving_objects[i] != mario) { moving_objects[i]->destroy(); } @@ -203,10 +202,13 @@ void doInputMainGame(std::shared_ptr scene) { auto rightmostX = scene->rightmost()->getRect().x + scene->rightmost()->getRect().w; scene->moveEverything((playerX > rightBarrier && rightmostX > width) * - (rightBarrier - playerX) / width, - 0); + (rightBarrier - playerX) / width, + 0); update = update || (playerX > rightBarrier && rightmostX > width); global_frames++; + if (mario->isDead()) { + g_death = true; + } } void doInput() { @@ -221,7 +223,7 @@ void doInput() { } } -void mainGameAdditional(std::shared_ptr &/*UNUSED*/) { +void mainGameAdditional(std::shared_ptr & /*UNUSED*/) { static auto base = SDL_GetTicks(); static int frames = 0; mario->setStanding(); @@ -326,10 +328,10 @@ SceneStruct mainGameScene(const std::string &level_path) { } void loadLevel(const std::string &level) { - //std::lock_guard lock(render_mutex); + // std::lock_guard lock(render_mutex); coin_count = 0; std::lock_guard lock(gamescene_mutex); - for(auto &scene : game_scenes) { + for (auto &scene : game_scenes) { scene.scene->resetScene(); } game_scenes.clear(); @@ -343,7 +345,7 @@ void loadLevel(const std::string &level) { } void loadLastLevel() { - if(last_load_level != "") { + if (last_load_level != "") { loadLevel(last_load_level); } } @@ -380,7 +382,8 @@ int main() { auto font = std::make_shared("testfont.ttf", 36); g_text_config = std::make_shared(font, "#FFFFFF", "#000000", 0.15); - game_scenes.push_back(createGameMainMenuScene(renderer, false, false, false)); + game_scenes.push_back( + createGameMainMenuScene(renderer, false, false, false)); std::thread inputThread(doInput); SDL_PumpEvents(); @@ -394,10 +397,10 @@ int main() { SDL_PumpEvents(); std::lock_guard lock(render_mutex); if (update) { - for(auto &scene : game_scenes) { + for (auto &scene : game_scenes) { scene.scene->updateSizeAndPosition(); } - if(update_count > 0) { + if (update_count > 0) { update_count--; } else { update = false; diff --git a/mario/mario.cpp b/mario/mario.cpp index 383d1be..dd8f781 100644 --- a/mario/mario.cpp +++ b/mario/mario.cpp @@ -1,4 +1,5 @@ #include "mario.hpp" +#include "blocks.hpp" #include "global_vars.hpp" #include "objectids.hpp" #include "sprites.hpp" @@ -34,6 +35,9 @@ Mario::Mario(int x, int y, const std::shared_ptr &renderer) Mario::Mario(const std::shared_ptr &renderer) : Mario(0, 0, renderer) {} void Mario::walkLeft() { + if (!controllable) { + return; + } if (on_ground) resumeAnimation(); addMovement(-side_movement, 0); @@ -46,6 +50,9 @@ void Mario::walkLeft() { } void Mario::walkRight() { + if (!controllable) { + return; + } if (on_ground) resumeAnimation(); addMovement(side_movement, 0); @@ -73,6 +80,9 @@ void Mario::handleVisitor(SDLPP::Visitor &visitor) { if (!jumping && on_ground) { resetMovementY(); setBaseRect(MARIO_STANDING_SRC); + if (!controllable) { + setDeath(); + } if (getMovement().getX() != 0) resumeAnimation(); // for some reason falling of the edge causes on_ground to be true, but @@ -120,10 +130,20 @@ void Mario::handleVisitor(SDLPP::Visitor &visitor) { if (m_visitor.hasMushroom()) { setType(LandType::UNDERWORLD); } + if (m_visitor.levelEnd() && controllable) { + if (std::abs(getPos().getX() - m_visitor.getEndPos().getX()) < + BLOCK_SIZE / 8) { + setPos(m_visitor.getEndPos().getX(), getPos().getY()); + stopMovement(); + } + } #endif } void Mario::jump() { + if (!controllable) { + return; + } if (!on_ground) return; jumping = true; @@ -172,3 +192,8 @@ void Mario::setWorldTypeSrc(LandType::Value /*UNUSED*/) { MarioBlock::setWorldTypeSrc(LandType::OVERWORLD); // TODO } + +void Mario::stopMovement() { + controllable = false; + setMovement(0, getMovement().getY()); +} diff --git a/mario/mario.hpp b/mario/mario.hpp index fd4d462..3bbbc14 100644 --- a/mario/mario.hpp +++ b/mario/mario.hpp @@ -17,8 +17,16 @@ public: void stopJump(); void custom_move(int ticks) override; void visit(SDLPP::Visitor &visitor) override; + bool isDead() { + return _death; + } private: + void setDeath(bool dead = true) { + _death = dead; + } + bool _death = false; + bool controllable = true; bool faces_right = true; double side_movement = 0.3; double jump_movement = 1.0; @@ -35,6 +43,7 @@ private: const double gravity_add_falling = jump_movement / (64.0 / 7.0); std::shared_ptr top_collision = nullptr; void setWorldTypeSrc(LandType::Value world) override; + void stopMovement(); }; #endif diff --git a/mario/visitors/mario_visitor.cpp b/mario/visitors/mario_visitor.cpp index abdd8d4..85c9be8 100644 --- a/mario/visitors/mario_visitor.cpp +++ b/mario/visitors/mario_visitor.cpp @@ -67,6 +67,12 @@ void MarioVisitor::visit(const SDLPP::RenderObject &obj) { case MUSHROOM_ID: mushroom = true; break; + case POLE_BOTTOM_ID: + case POLE_TOP_ID: + case FLAG_ID: + _end = true; + endPos = obj.getPos(); + break; default: break; } diff --git a/mario/visitors/mario_visitor.hpp b/mario/visitors/mario_visitor.hpp index 6f49e06..eeab795 100644 --- a/mario/visitors/mario_visitor.hpp +++ b/mario/visitors/mario_visitor.hpp @@ -108,6 +108,14 @@ public: return _bounce; } + bool levelEnd() { + return _end; + } + + const SDLPP::Vec2D &getEndPos() { + return endPos; + } + private: bool onGround = false; double groundY = 0; @@ -130,6 +138,8 @@ private: bool mushroom = false; std::vector> &_moving_objects; bool _bounce = false; + bool _end = false; + SDLPP::Vec2D endPos; }; #endif