From d4393ef179e287148cd4cfdc3a3abee9e9cf4413 Mon Sep 17 00:00:00 2001 From: zvon Date: Fri, 6 Aug 2021 18:49:58 +0200 Subject: [PATCH] Mario: better handling of screen resize, when showing FPS consider input handling as well --- mario/main.cpp | 66 +++++++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/mario/main.cpp b/mario/main.cpp index 0a1c6ff..1369aba 100644 --- a/mario/main.cpp +++ b/mario/main.cpp @@ -26,6 +26,7 @@ std::shared_ptr< SDLPP::Renderer > renderer = nullptr; std::shared_ptr< SDLPP::TextRenderer > fps = nullptr; std::shared_ptr< SDLPP::TextRenderer > coins = nullptr; int coin_count = 0; +int global_frames = 0; std::vector< std::shared_ptr< MarioBlock > > moving_objects = {}; @@ -77,6 +78,32 @@ void handleKeyUp( SDL_Keycode key ) { } } +void moveToMarioPosition( SDLPP::Scene &scene, + SDLPP::Vec2D< double > &prev_mario ) { + auto rendDims = renderer->getDoubleDimensions(); + if ( leftStop ) { + auto left = + rendDims.getX() < 2.0 ? -( rendDims.getX() - 1 ) / 2.0 - 0.1 : -0.5; + leftStop->setPos( left, 0 ); + } + auto mario_pos_difference = prev_mario - mario->getAbsolutePos(); + // sometimes there is a concurrency problem and prev_pos == cur_pos, in + // that case move everything so Mario is standing on the left edge of the + // screen + if(mario_pos_difference.getX() < 0.01 && mario_pos_difference.getX() > -0.01) { + // 0.01 is the width of visible leftStop + scene.moveEverything(-(mario->getAbsolutePos().getX() - 0.01), 0); + } else { + scene.moveEverything( mario_pos_difference.getX(), 0 ); + } + scene.updateSizeAndPosition(); + auto left_stop_rightmost = leftStop->getDoubleRect().first.getX() + + leftStop->getDoubleRect().second.getX(); + if ( mario->getPos().getX() < left_stop_rightmost ) { + mario->setPos( left_stop_rightmost, mario->getPos().getY() ); + } +} + void pollEvents( SDLPP::Scene &scene ) { SDL_Event event; while ( SDLPP::getSDLEvent( event ) ) { @@ -94,32 +121,9 @@ void pollEvents( SDLPP::Scene &scene ) { break; case SDL_WINDOWEVENT: if ( event.window.event == SDL_WINDOWEVENT_RESIZED ) { + auto prev_mario_pos = mario->getAbsolutePos(); scene.updateSizeAndPosition(); - if ( leftStop ) { - auto rendDims = renderer->getDoubleDimensions(); - auto left = rendDims.getX() < 2.0 - ? -( rendDims.getX() - 1 ) / 2.0 - 0.1 - : -0.5; - leftStop->setPos( left, 0 ); - } - auto dimensions = renderer->getDoubleDimensions(); - auto leftmost = -( dimensions.getX() - 1 ) / 2.0; - auto rightmost = 1 - leftmost; - auto marioPos = mario->getPos(); - if ( marioPos.getX() < leftmost ) { - scene.moveEverything( leftmost - marioPos.getX(), 0 ); - update = true; - } else if ( marioPos.getX() > rightmost ) { - scene.moveEverything( marioPos.getX() - rightmost, 0 ); - update = true; - } - if ( mario->getPos().getX() < - leftStop->getDoubleRect().first.getX() + - leftStop->getDoubleRect().second.getX() ) { - mario->setPos( leftStop->getDoubleRect().first.getX() + - leftStop->getDoubleRect().second.getX(), - mario->getPos().getY() ); - } + moveToMarioPosition( scene, prev_mario_pos ); } default: break; @@ -138,11 +142,12 @@ void doInput( std::shared_ptr< SDLPP::Scene > scene ) { scene->updateScene(); auto prev_coin_count = coin_count; // TODO visit all moving objects - auto visitor = getVisitor(*mario, *scene, quit, coin_count, moving_objects); + auto visitor = + getVisitor( *mario, *scene, quit, coin_count, moving_objects ); scene->visitCollisions( *mario, *visitor ); mario->handleVisitor( *visitor ); - if(coin_count != prev_coin_count) { + if ( coin_count != prev_coin_count ) { coins->changeText( std::to_string( coin_count ) + " COINS" ); } // if player is > 0.7 of playground, move everything left @@ -155,7 +160,8 @@ void doInput( std::shared_ptr< SDLPP::Scene > scene ) { ( playerX > rightBarrier && rightmostX > width ) * ( rightBarrier - playerX ) / width, 0 ); - update = true; + update = playerX > rightBarrier && rightmostX > width; + global_frames++; } } @@ -257,6 +263,10 @@ int main() { renderer->presentRenderer(); frames++; if ( SDL_GetTicks() - base >= 1000 ) { + if ( global_frames < frames ) { + frames = global_frames; + } + global_frames = 0; fps->changeText( std::to_string( frames ) + " fps" ); frames = 0; base = SDL_GetTicks();