#include "../sdlpp/sdlpp.hpp" #include "config.hpp" #include "custom_classes.hpp" #include "scenes.hpp" #include "global_vars.hpp" #include "functions.hpp" #include #include #include #ifdef _WIN32 #include "../sdlpp/SDL2/SDL2_framerate.h" #include #include #include #else #include #endif // UNIX std::vector< std::shared_ptr< SDLPP::RenderObject > > line_coliders{}; void updateScore() { g_score_texture->changeText( std::to_string( g_score ) ); g_score_texture->updateSizeAndPosition(); } void doInput() { FPSmanager gFPS; SDL_initFramerate( &gFPS ); SDL_setFramerate( &gFPS, 200 ); auto base = SDL_GetTicks(); while ( !g_quit ) { base = SDL_GetTicks(); SDL_framerateDelay( &gFPS ); g_input_functions.back()( g_main_scene, base, line_coliders ); } } void prepareShadowColider( std::shared_ptr< SDLPP::Renderer > r ) { g_shadow_colider = std::make_shared< SDLPP::RectangleRender >( 0, TOP_BORDER, BLOCK_SIZE, BOTTOM_BORDER - TOP_BORDER, r ); g_shadow_colider->addCollision( SDLPP::RectColider( 0.1, 0.01, 0.8, 0.98 ) ); g_shadow_colider->setId( COLIDER_ID ); g_shadow_colider->setStatic(); g_shadow_colider->centerX(); } #ifdef _WIN32 int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR szCmdLine, int nCmdShow ) { #else int main() { #endif SDLPP::init(); SDLPP::Window w( "Tetris clone!" ); w.setResizable( true ); auto renderer = std::make_shared< SDLPP::Renderer >( w ); g_active_renderer = renderer; renderer->setBlendMode( SDL_BLENDMODE_BLEND ); prepareShadowColider( renderer ); g_font = std::make_shared< SDLPP::Font >( "testfont.ttf", 36 ); g_font_config = std::make_shared< SDLPP::FontConfiguration >( g_font, colors["text"], colors["text_out"], 0.1 ); g_main_scene = prepareMainScene( renderer ); line_coliders = g_main_scene->getObjects( { COLIDER_ID } ); g_score_texture = std::dynamic_pointer_cast< SDLPP::TextRenderer >( g_main_scene->getObjects( { SCORE_TEXTURE_ID } )[0] ); g_active_scenes.push_back( g_main_scene ); g_main_scene->saveScene(); g_menu_scene = prepareMenuScene( renderer ); g_game_over_scene = prepareGameOverScene( renderer ); g_options_scene = prepareOptionsScene( renderer ); auto base = SDL_GetTicks(); int frames = 0; std::srand( std::time( nullptr ) ); FPSmanager gFPS; SDL_initFramerate( &gFPS ); SDL_setFramerate( &gFPS, 60 ); std::thread inputThread( doInput ); inputThread.detach(); g_next_object = g_tetrisFunctions[std::rand() / ( ( RAND_MAX + 1u ) / 7 )]( renderer, g_main_scene ); g_next_object->setPos( 0.9, 0.5 ); g_input_functions.push_back( mainSceneInput ); while ( !g_quit ) { SDL_PumpEvents(); SDL_framerateDelay( &gFPS ); if ( !g_cur_object && g_checked_line ) { std::lock_guard< std::mutex > guard( g_movement_mutex ); if ( !g_next_object ) { g_next_object = g_tetrisFunctions[std::rand() / ( ( RAND_MAX + 1u ) / 7 )]( g_main_scene->getRendererShared(), g_main_scene ); g_next_object->setPos( 0.9, 0.5 ); } g_cur_object = g_next_object; g_cur_object->setPos( 0.5, TOP_BORDER - BLOCK_SIZE ); g_cur_shadow = g_cur_object->copySelf(); g_cur_shadow->turnIntoShadow(); for ( auto &piece : g_cur_shadow->getObjects() ) { // make it so shadow gets covered by g_cur_object g_main_scene->moveZ( piece, -4 ); } updateShadow( *g_main_scene ); auto rand_index = std::rand() / ( ( RAND_MAX + 1u ) / 7 ); int retries = 0; while ( g_bag[rand_index] < 4 ) { rand_index = ( rand_index + 1 ) % 7; retries++; // bag is empty if ( retries == 7 ) { g_game_over_scene->updateSizeAndPosition(); g_active_scenes.push_back( g_game_over_scene ); g_input_functions.push_back( gameOverSceneInput ); break; } } g_next_object.reset(); g_next_object = g_tetrisFunctions[rand_index]( renderer, g_main_scene ); g_next_object->setPos( 0.9, 0.5 ); g_checked_line = false; } if ( g_update_score ) { updateScore(); g_update_score = false; } if ( g_update_colors ) { updateColors(); g_update_colors = false; } if ( g_update_3d ) { updateBlocks(); g_update_3d = false; } if ( g_update_size ) { updateSize(); g_update_size = false; } for(size_t i = 0; i < g_update_scenes.size(); i++) { g_update_scenes.back()->updateSizeAndPosition(); g_update_scenes.pop_back(); } for(size_t i = 0; i < g_update_objects.size(); i++) { g_update_objects.back()->updateSizeAndPosition(); g_update_objects.pop_back(); } renderer->clearRenderer(); for ( auto &x : g_active_scenes ) { x->renderScene( false ); } renderer->presentRenderer(); g_wait_for_anim = false; frames++; if ( SDL_GetTicks() - base >= 1000 ) { base = SDL_GetTicks(); std::cout << "FPS: " << frames << std::endl; frames = 0; } } return 0; }