From b8c56c06fd828ed8dc3375929d0b223e4a651bd8 Mon Sep 17 00:00:00 2001 From: zvon Date: Thu, 27 May 2021 16:33:00 +0200 Subject: [PATCH] Mario: better side collision handling --- mario/main.cpp | 8 ++++++-- mario/mario.cpp | 26 ++++++++++++++------------ mario/mario.hpp | 2 +- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/mario/main.cpp b/mario/main.cpp index b4f6bf6..93b1667 100644 --- a/mario/main.cpp +++ b/mario/main.cpp @@ -10,6 +10,7 @@ #endif // UNIX #include +#include #include "global_vars.hpp" #include "objectids.hpp" #include "blocks.hpp" @@ -24,6 +25,8 @@ std::shared_ptr< SDLPP::RectangleRender > leftStop = nullptr; std::shared_ptr< SDLPP::Renderer > renderer = nullptr; std::shared_ptr< SDLPP::TextRenderer > fps = nullptr; +std::mutex render_mutex; + void handleKeyDown( SDL_Keycode key, SDLPP::Scene &scene ) { switch ( key ) { case SDLK_ESCAPE: @@ -125,14 +128,14 @@ void doInput( std::shared_ptr< SDLPP::Scene > scene ) { while ( true ) { SDL_framerateDelay( &gFPS ); pollEvents( *scene ); - auto prevPos = mario->getDoubleRect().first; + std::lock_guard lock(render_mutex); scene->updateScene(); MarioVisitor mv(mario->getMovement().getY() < 0); scene->visitCollisions( *mario, mv ); if ( mv.isDead() ) { quit = true; } - mario->handleVisitor(mv, prevPos); + mario->handleVisitor(mv); // if player is > 0.7 of playground, move everything left auto playerX = mario->getRect().x; @@ -227,6 +230,7 @@ int main() { while ( !quit ) { SDL_PumpEvents(); SDL_framerateDelay( &gFPS ); + std::lock_guard lock(render_mutex); mario->setStanding(); if(update) { scene->updateSizeAndPosition(); diff --git a/mario/mario.cpp b/mario/mario.cpp index caf0805..bd7bbe5 100644 --- a/mario/mario.cpp +++ b/mario/mario.cpp @@ -12,18 +12,21 @@ Mario::Mario(const std::shared_ptr< SDLPP::Renderer > &renderer) : SDLPP::Rectan setMovement( 0, 0 ); setMovementSpeed( 1 ); auto bottom_detect = SDLPP::RectColider( 0.2, 1, 0.6, 0, MARIO_FLOOR_DETECT ); + bottom_detect.setColor("#FF0000"); + bottom_detect.setOutlineColor("#FF0000"); bottom_detect.setMinHeight(1); addCollision(bottom_detect); addCollision( - SDLPP::RectColider( 0.05, 0.1, 0.1, 0.89, MARIO_LEFT_SIDE_DETECT ) ); + SDLPP::RectColider( 0, 0.1, 0.1, 0.85, MARIO_LEFT_SIDE_DETECT ) ); addCollision( - SDLPP::RectColider( 0.85, 0.1, 0.1, 0.89, MARIO_RIGHT_SIDE_DETECT ) ); + SDLPP::RectColider( 0.9, 0.1, 0.1, 0.85, MARIO_RIGHT_SIDE_DETECT ) ); addCollision( - SDLPP::RectColider( 0.05, 0, 0.1, 0.1, MARIO_TOP_LEFT_DETECT ) ); + SDLPP::RectColider( 0, 0, 0.1, 0.1, MARIO_TOP_LEFT_DETECT ) ); addCollision( - SDLPP::RectColider( 0.85, 0, 0.1, 0.1, MARIO_TOP_LEFT_DETECT ) ); + SDLPP::RectColider( 0.9, 0, 0.1, 0.1, MARIO_TOP_LEFT_DETECT ) ); top_collision = std::make_shared( 0.5, 0, 0.2, 0.15, MARIO_TOP_DETECT ); addCollision( top_collision ); + setColiderColor("#FF0000"); setStatic( false ); } void Mario::walkLeft() { @@ -56,7 +59,7 @@ void Mario::setStanding() { } } -void Mario::handleVisitor(MarioVisitor &visitor, SDLPP::Vec2D previous_position) { +void Mario::handleVisitor(MarioVisitor &visitor) { // TODO - https://web.archive.org/web/20130807122227/http://i276.photobucket.com/albums/kk21/jdaster64/smb_playerphysics.png // handle gravity on_ground = visitor.isOnGround(); @@ -71,6 +74,10 @@ void Mario::handleVisitor(MarioVisitor &visitor, SDLPP::Vec2D previous_p setPos(getPos().getX(), visitor.getGroundY() - BLOCK_SIZE); } } + // if we just left ground gravity didn't work in custom_move + if(!on_ground && !jumping && getMovement().getY() == 0) { + addMovement(0, 2*gravity_add_falling); + } if(visitor.topBlock() && getMovement().getY() < 0) { resetMovementY(); stop_jump = true; @@ -78,16 +85,11 @@ void Mario::handleVisitor(MarioVisitor &visitor, SDLPP::Vec2D previous_p // make sure Mario isn't stuck inside a wall // TODO more readable function names if ( visitor.isStopped() ) { - if(visitor.getStopX() > previous_position.getX()) - previous_position = {visitor.getStopX(), previous_position.getY()}; - setPos( previous_position.getX(), getPos().getY() ); + setPos( visitor.getStopX(), getPos().getY()); } else if ( visitor.canGoLeft() != visitor.canGoRight() ) { SDLPP::Vec2D next_pos = { visitor.getMovementBlockage().getX() + (visitor.canGoLeft() * -1 + visitor.canGoRight() * 1) * BLOCK_SIZE, getPos().getY() }; - if((visitor.canGoLeft() && next_pos.getX() > previous_position.getX()) || (visitor.canGoRight() && next_pos.getX() < previous_position.getX())) { - next_pos = previous_position; - } setPos(next_pos); - } else if (visitor.moveTop() && (jumping && !stop_jump)) { + } else if (visitor.moveTop() && jumping && !stop_jump) { auto objPos = visitor.getRightLeftPos(); if(objPos.getX() < getPos().getX()) { setPos( objPos.getX() + BLOCK_SIZE, getPos().getY() ); diff --git a/mario/mario.hpp b/mario/mario.hpp index 64813bf..eb4f360 100644 --- a/mario/mario.hpp +++ b/mario/mario.hpp @@ -11,7 +11,7 @@ public: void walkLeft(); void walkRight(); void setStanding(); - void handleVisitor(MarioVisitor &visitor, SDLPP::Vec2D previous_position); + void handleVisitor(MarioVisitor &visitor); void jump(); void stopJump(); virtual void custom_move( int ticks ) override;