180 lines
5.8 KiB
C++
180 lines
5.8 KiB
C++
#include "../sdlpp/sdlpp.hpp"
|
|
#include "config.hpp"
|
|
#include "custom_classes.hpp"
|
|
#include "scenes.hpp"
|
|
#include "global_vars.hpp"
|
|
#include "functions.hpp"
|
|
#include <thread>
|
|
#include <chrono>
|
|
#include <mutex>
|
|
#ifdef _WIN32
|
|
#include "../sdlpp/SDL2/SDL2_framerate.h"
|
|
#include <ctime>
|
|
#include <string>
|
|
#include <windows.h>
|
|
#else
|
|
#include <SDL2/SDL2_framerate.h>
|
|
#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->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER);
|
|
}
|
|
|
|
#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;
|
|
}
|
|
while ( !g_update_scenes.empty() ) {
|
|
g_update_scenes.back()->updateSizeAndPosition();
|
|
g_update_scenes.pop_back();
|
|
}
|
|
while ( !g_update_objects.empty() ) {
|
|
g_update_objects.back()->updateSizeAndPosition();
|
|
g_update_objects.pop_back();
|
|
}
|
|
|
|
{
|
|
std::lock_guard< std::mutex > guard( g_render_mutex );
|
|
renderer->clearRenderer();
|
|
for ( size_t i = 0; i < g_active_scenes.size(); i++ ) {
|
|
g_active_scenes[i]->updateScene();
|
|
g_active_scenes[i]->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;
|
|
}
|