#include "../sdlpp/sdlpp.hpp" #include "sprites.hpp" #ifdef _WIN32 #include "../sdlpp/SDL2/SDL2_framerate.h" #include #include #include #else #include #endif // UNIX #include #include #include "global_vars.hpp" #include "objectids.hpp" #include "blocks.hpp" #include "maploader.hpp" #include "mario.hpp" #include "visitors/visitor_generator.hpp" bool quit = false; bool update = false; std::shared_ptr< Mario > mario = nullptr; std::shared_ptr< SDLPP::RectangleRender > leftStop = nullptr; 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; std::vector< std::shared_ptr< MarioBlock > > moving_objects = {}; std::mutex render_mutex; void handleKeyDown( SDL_Keycode key, SDLPP::Scene &scene ) { switch ( key ) { case SDLK_ESCAPE: quit = true; break; case SDLK_a: mario->walkLeft(); break; case SDLK_d: mario->walkRight(); break; case SDLK_SPACE: case SDLK_w: mario->jump(); break; case SDLK_s: break; case SDLK_r: scene.getRenderer().setRenderColiders( !scene.getRenderer().getRenderColiders() ); break; case SDLK_f: if ( fps ) { fps->setHidden( !fps->getHidden() ); } default: break; } } void handleKeyUp( SDL_Keycode key ) { switch ( key ) { case SDLK_a: mario->walkRight(); break; case SDLK_d: mario->walkLeft(); break; case SDLK_SPACE: case SDLK_w: mario->stopJump(); default: break; } } void pollEvents( SDLPP::Scene &scene ) { SDL_Event event; while ( SDLPP::getSDLEvent( event ) ) { switch ( event.type ) { case SDL_QUIT: quit = true; break; case SDL_KEYDOWN: if ( !event.key.repeat ) { handleKeyDown( event.key.keysym.sym, scene ); } break; case SDL_KEYUP: handleKeyUp( event.key.keysym.sym ); break; case SDL_WINDOWEVENT: if ( event.window.event == SDL_WINDOWEVENT_RESIZED ) { 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() ); } } default: break; } } } void doInput( std::shared_ptr< SDLPP::Scene > scene ) { FPSmanager gFPS; SDL_initFramerate( &gFPS ); SDL_setFramerate( &gFPS, 200 ); while ( true ) { SDL_framerateDelay( &gFPS ); pollEvents( *scene ); std::lock_guard< std::mutex > lock( render_mutex ); scene->updateScene(); auto prev_coin_count = coin_count; // TODO visit all 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) { coins->changeText( std::to_string( coin_count ) + " COINS" ); } // if player is > 0.7 of playground, move everything left auto playerX = mario->getRect().x; auto width = scene->getWidth(); auto rightBarrier = width * 0.7; auto rightmostX = scene->rightmost()->getRect().x + scene->rightmost()->getRect().w; scene->moveEverything( ( playerX > rightBarrier && rightmostX > width ) * ( rightBarrier - playerX ) / width, 0 ); update = true; } } #ifdef _WIN32 int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR szCmdLine, int nCmdShow ) { #else int main() { #endif SDLPP::init(); SDLPP::Window w( "Mario clone!" ); w.setResizable( true ); renderer = std::make_shared< SDLPP::Renderer >( w ); renderer->setBlendMode( SDL_BLENDMODE_BLEND ); // prepare global vars g_terrain_texture = std::make_shared< SDLPP::Texture >( renderer, "sprites/terrain.png", MARIO_OVERWORLD_COLORKEY ); auto scene = std::make_shared< SDLPP::Scene >( renderer ); g_playground = scene; auto bg = std::make_shared< SDLPP::RectangleRender >( 0, 0, 10, 10, renderer, MARIO_OVERWORLD_COLORKEY, true ); bg->setPermanent(); bg->setStatic(); bg->setId( 1 ); scene->addObject( bg ); g_mario_texture = std::make_shared< SDLPP::Texture >( renderer, "sprites/mario.png", MARIO_OVERWORLD_COLORKEY ); g_translucent_terrain_texture = std::make_shared< SDLPP::Texture >( renderer, "sprites/terrain.png", MARIO_OVERWORLD_COLORKEY ); g_translucent_terrain_texture->setAlpha( 100 ); mario = std::make_shared< Mario >( renderer ); scene->addObject( mario ); auto defeat = std::make_shared< SDLPP::RectangleRender >( 0, 1.01, 0, 0, renderer ); defeat->setId( DEATH_ID ); defeat->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); defeat->setPermanent(); auto defeatCol = SDLPP::RectColider( -1, 0, -1, -1 ); defeatCol.setInfinite(); defeat->addCollision( defeatCol ); scene->addObject( defeat ); leftStop = std::make_shared< SDLPP::RectangleRender >( -0.1, 0, 0.11, 0, renderer ); leftStop->setId( STOP_MOVEMENT ); leftStop->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); leftStop->setPermanent(); auto leftStopCol = SDLPP::RectColider( 0, -1, 1, -1 ); leftStopCol.setInfinite(); leftStop->addCollision( leftStopCol ); leftStop->setColiderColor( "#FF00FF" ); scene->addObject( leftStop ); loadMap( scene, mario, "test_binary2.bin" ); auto font = std::make_shared< SDLPP::Font >( "testfont.ttf", 36 ); fps = std::make_shared< SDLPP::TextRenderer >( 0.2, 0, 0.78, 0.1, renderer, font, "0fps", "#FFFFFF", "#000000", 0.1, SDLPP_TEXT_RIGHT ); fps->setAlignment( SDLPP::OBJ_END, SDLPP::OBJ_START ); fps->setId( 0 ); fps->setPermanent(); fps->setHidden( true ); scene->addObject( fps ); coins = std::make_shared< SDLPP::TextRenderer >( 0.2, 0, 0.78, 0.1, renderer, font, "0 COINS", "#FFFFFF", "#000000", 0.1, SDLPP_TEXT_RIGHT ); coins->setAlignment( SDLPP::OBJ_START, SDLPP::OBJ_START ); coins->setId( 0 ); coins->setPermanent(); scene->addObject( coins ); FPSmanager gFPS; SDL_initFramerate( &gFPS ); SDL_setFramerate( &gFPS, 60 ); auto base = SDL_GetTicks(); int frames = 0; std::thread inputThread( doInput, scene ); inputThread.detach(); scene->moveEverything( -mario->getDoubleRect().first.getX() + 0.2, 0 ); update = true; while ( !quit ) { SDL_PumpEvents(); SDL_framerateDelay( &gFPS ); std::lock_guard< std::mutex > lock( render_mutex ); mario->setStanding(); if ( update ) { scene->updateSizeAndPosition(); update = false; } scene->renderScene(); renderer->presentRenderer(); frames++; if ( SDL_GetTicks() - base >= 1000 ) { fps->changeText( std::to_string( frames ) + " fps" ); frames = 0; base = SDL_GetTicks(); } } return 0; }