#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_visitor.hpp" #include "mario.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::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 lock(render_mutex); scene->updateScene(); MarioVisitor mv(mario->getMovement().getY() < 0); scene->visitCollisions( *mario, mv ); if ( mv.isDead() ) { quit = true; } mario->handleVisitor(mv); // 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(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); 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 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; }