diff --git a/mario/blocks.cpp b/mario/blocks.cpp index 5049871..36e9e59 100644 --- a/mario/blocks.cpp +++ b/mario/blocks.cpp @@ -4,6 +4,7 @@ #include "sprites.hpp" #include "editor_visitor.hpp" #include +#include "mario_visitor.hpp" MarioBlock::MarioBlock( int x, int y, std::shared_ptr< SDLPP::Renderer > renderer, @@ -22,7 +23,7 @@ void MarioBlock::visit( SDLPP::Visitor &visitor ) { visitor.getVisitorType() == VisitorType::Modifier ) { destroy(); } - if(visitor.getFromId() == MARIO_TOP_DETECT && _destructible) { + if(visitor.getFromId() == MARIO_TOP_DETECT && _destructible && dynamic_cast(visitor).canDestroy()) { destroy(); } visitor.visit( *this ); diff --git a/mario/main.cpp b/mario/main.cpp index 91f745d..102f79d 100644 --- a/mario/main.cpp +++ b/mario/main.cpp @@ -119,7 +119,7 @@ void doInput( std::shared_ptr< SDLPP::Scene > scene ) { pollEvents( *scene ); auto prevPos = mario->getDoubleRect().first; scene->updateScene(); - MarioVisitor mv{}; + MarioVisitor mv(mario->getMovement().getY() < 0); scene->visitCollisions( *mario, mv ); if ( mv.isDead() ) { quit = true; diff --git a/mario/mario.cpp b/mario/mario.cpp index a07f3e4..5249f6b 100644 --- a/mario/mario.cpp +++ b/mario/mario.cpp @@ -14,11 +14,15 @@ Mario::Mario(const std::shared_ptr< SDLPP::Renderer > &renderer) : SDLPP::Rectan addCollision( SDLPP::RectColider( 0.21, 0.85, 0.65, 0.25, MARIO_FLOOR_DETECT ) ); addCollision( - SDLPP::RectColider( 0, 0.1, 0.1, 0.8, MARIO_LEFT_SIDE_DETECT ) ); + SDLPP::RectColider( 0.05, 0.1, 0.1, 0.8, MARIO_LEFT_SIDE_DETECT ) ); addCollision( - SDLPP::RectColider( 0.9, 0.1, 0.1, 0.8, MARIO_RIGHT_SIDE_DETECT ) ); + SDLPP::RectColider( 0.85, 0.1, 0.1, 0.8, MARIO_RIGHT_SIDE_DETECT ) ); addCollision( - SDLPP::RectColider( 0.45, 0, 0.1, 0.15, MARIO_TOP_DETECT ) ); + SDLPP::RectColider( 0.05, 0, 0.1, 0.1, MARIO_TOP_LEFT_DETECT ) ); + addCollision( + SDLPP::RectColider( 0.85, 0, 0.1, 0.1, MARIO_TOP_LEFT_DETECT ) ); + addCollision( + SDLPP::RectColider( 0.35, 0, 0.3, 0.15, MARIO_TOP_DETECT ) ); setStatic( false ); } void Mario::walkLeft() { @@ -48,19 +52,8 @@ void Mario::setStanding() { } void Mario::handleVisitor(MarioVisitor &visitor, SDLPP::Vec2D previous_position) { + // TODO - https://web.archive.org/web/20130807122227/http://i276.photobucket.com/albums/kk21/jdaster64/smb_playerphysics.png // handle gravity - // TODO - https://haydnscarlett.wordpress.com/2020/07/30/marios-jump/ -/* if (jumping) { - if(stop_jump && getPos().getY() - min_jump < 0.05) { - jumping = false; - resetMovementY(); - } else if( getPos().getY() - max_jump < 0.05 ) { - jumping = false; - resetMovementY(); - } else if ( getPos().getY() - slow_jump < 0.05 && getMovement().getY() < -1*jump_movement/5 ) { - addMovement(0, jump_movement/50); - } - }*/ on_ground = visitor.isOnGround(); if(!jumping && on_ground) { resetMovementY(); @@ -75,12 +68,19 @@ void Mario::handleVisitor(MarioVisitor &visitor, SDLPP::Vec2D previous_p } if(visitor.topBlock() && getMovement().getY() < 0) { resetMovementY(); + stop_jump = true; } // make sure Mario isn't stuck inside a wall - if ( visitor.isStopped() || - ( !visitor.canGoLeft() && previous_position.getX() > getPos().getX() ) || - ( !visitor.canGoRight() && previous_position.getX() < getPos().getX() ) ) { + // TODO more readable function names + if ( visitor.isStopped() || !visitor.canGoLeft() || !visitor.canGoRight() ) { setPos( previous_position.getX(), getPos().getY() ); + } else if (visitor.moveTop() && (jumping && !stop_jump)) { + auto objPos = visitor.getRightLeftPos(); + if(objPos.getX() < getPos().getX()) { + setPos( objPos.getX() + BLOCK_SIZE, getPos().getY() ); + } else { + setPos( objPos.getX() - BLOCK_SIZE, getPos().getY() ); + } } } diff --git a/mario/mario_visitor.cpp b/mario/mario_visitor.cpp index 7d12a5f..6991538 100644 --- a/mario/mario_visitor.cpp +++ b/mario/mario_visitor.cpp @@ -17,6 +17,9 @@ void MarioVisitor::visit( const SDLPP::RenderObject &obj ) { right = true; } else if (from == MARIO_TOP_DETECT) { top_hit = true; + } else if (from == MARIO_TOP_LEFT_DETECT || from == MARIO_TOP_RIGHT_DETECT) { + rightleftpos = obj.getPos(); + top_left_right = true; } break; case DEATH_ID: diff --git a/mario/mario_visitor.hpp b/mario/mario_visitor.hpp index 34ab124..4355c2f 100644 --- a/mario/mario_visitor.hpp +++ b/mario/mario_visitor.hpp @@ -6,7 +6,7 @@ class MarioVisitor : public SDLPP::Visitor { public: - MarioVisitor() {} + MarioVisitor(bool is_jumping) : jumping(is_jumping) {} virtual void visit( const SDLPP::RenderObject &obj ) override; bool isOnGround() { return onGround; @@ -44,6 +44,16 @@ public: bool topBlock() { return top_hit; } + bool moveTop() { + return top_left_right; + } + const SDLPP::Vec2D &getRightLeftPos() { + return rightleftpos; + } + + bool canDestroy() { + return jumping && !top_hit; + } private: bool onGround = false; @@ -56,6 +66,9 @@ private: bool right = false; uint64_t _type = 0; bool top_hit = false; + SDLPP::Vec2D rightleftpos; + bool top_left_right = false; + bool jumping; }; #endif diff --git a/mario/objectids.hpp b/mario/objectids.hpp index 46d5151..8b4218f 100644 --- a/mario/objectids.hpp +++ b/mario/objectids.hpp @@ -74,6 +74,8 @@ #define MARIO_LEFT_SIDE_DETECT 0x2002 #define MARIO_RIGHT_SIDE_DETECT 0x2003 #define MARIO_TOP_DETECT 0x2004 +#define MARIO_TOP_LEFT_DETECT 0x2005 +#define MARIO_TOP_RIGHT_DETECT 0x2006 #define EDITOR_EDIT_SQUARE 0xF001 #define EDITOR_MOUSE_ID 0xF002