diff --git a/tetris/Makefile b/tetris/Makefile index 3927437..b1e1d4c 100644 --- a/tetris/Makefile +++ b/tetris/Makefile @@ -10,7 +10,7 @@ OUTPUTFLAG = -Fo else UNAME_S := $(shell uname -s) CXX ?= g++ -CXXFLAGS = -std=c++14 -Wall -Wextra -pedantic -O2 #-g -fsanitize=address +CXXFLAGS = -std=c++14 -Wall -Wextra -pedantic -O2 -DDEBUG #-g -fsanitize=address OBJEXT = o LDFLAGS ?= -lSDL2 -lSDL2_image -lSDL2_gfx -lSDL2_ttf -pthread OUTPUTFLAG = -o diff --git a/tetris/config.hpp b/tetris/config.hpp index 01a7ef7..a8cdaec 100644 --- a/tetris/config.hpp +++ b/tetris/config.hpp @@ -20,6 +20,16 @@ #define MENU_ITEM_ID 0x10000001 #define MENU_BACKGROUND_ID 0x10000002 #define MENU_TEXT_ID 0x10000003 +#define MENU_RESUME_ID 0x10000004 +#define MENU_OPTIONS_ID 0x10000005 +#define MENU_RESTART_ID 0x10000006 +#define MENU_QUIT_ID 0x10000007 +#define MENU_MOUSE_ID 0x10000008 + +#define OPTIONS_COLOR_ID 0x10000009 +#define OPTIONS_SHADOW_ID 0x1000000A +#define OPTIONS_3D_ID 0x1000000B +#define OPTIONS_SAVE_ID 0x1000000C #define LEFT_BORDER 0.3 #define RIGHT_BORDER 0.7 diff --git a/tetris/scenes.cpp b/tetris/scenes.cpp index e982947..4e723c6 100644 --- a/tetris/scenes.cpp +++ b/tetris/scenes.cpp @@ -2,7 +2,10 @@ #include "config.hpp" #include "functions.hpp" #include "global_vars.hpp" +#include "../sdlpp/sdlpp_mouse.hpp" +#include +#include #include constexpr uint64_t MAIN_MENU_RESUME = 0; @@ -30,7 +33,7 @@ void addMainSceneItems( SDLPP::Scene &scene, #ifdef FEATURE auto testcircle = std::make_shared< SDLPP::CircleRender >( LEFT_BORDER, 0.2, 0.05, r, "#FF00AA", true ); - testcircle->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + testcircle->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); scene.addObject( testcircle ); #endif @@ -43,7 +46,7 @@ void addMainSceneItems( SDLPP::Scene &scene, colider->addCollision( SDLPP::RectColider( 0.01, 0.1, 0.98, 0.8 ) ); colider->setId( COLIDER_ID ); colider->setStatic(); - colider->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + colider->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); scene.addObject( colider ); } @@ -54,7 +57,7 @@ void addMainSceneItems( SDLPP::Scene &scene, auto line = std::make_shared< SDLPP::LineRenderer >( LEFT_BORDER, posy, RIGHT_BORDER, posy, r, colors["line"] ); line->setStatic(); - line->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + line->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); line->setId( LINE_ID ); scene.addObject( line ); } @@ -66,7 +69,7 @@ void addMainSceneItems( SDLPP::Scene &scene, posx, TOP_BORDER + BLOCK_SIZE, posx, BOTTOM_BORDER, r, colors["line"] ); line->setStatic(); - line->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + line->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); line->setId( LINE_ID ); scene.addObject( line ); } @@ -74,14 +77,14 @@ void addMainSceneItems( SDLPP::Scene &scene, auto left_barrier = std::make_shared< SDLPP::RectangleRender >( LEFT_BORDER - 0.02, 0, 0.02, BOTTOM_BORDER, r, colors["barrier"], true ); - left_barrier->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + left_barrier->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); left_barrier->setStatic(); left_barrier->setId( BARRIER_ID ); scene.addObject( left_barrier ); auto right_barrier = std::make_shared< SDLPP::RectangleRender >( RIGHT_BORDER, 0, 0.02, BOTTOM_BORDER, r, colors["barrier"], true ); - right_barrier->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + right_barrier->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); right_barrier->setStatic(); right_barrier->setId( BARRIER_ID ); scene.addObject( right_barrier ); @@ -89,14 +92,14 @@ void addMainSceneItems( SDLPP::Scene &scene, auto bottom_barrier = std::make_shared< SDLPP::RectangleRender >( LEFT_BORDER - 0.02, BOTTOM_BORDER, RIGHT_BORDER - LEFT_BORDER + 0.04, 0.02, r, colors["barrier"], true ); - bottom_barrier->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + bottom_barrier->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); bottom_barrier->setStatic(); bottom_barrier->setId( BARRIER_ID ); scene.addObject( bottom_barrier ); auto tetris = std::make_shared< SDLPP::TextRenderer >( 0.4, 0, 0.2, 0.1, r, "TETRIS", g_font_config ); - tetris->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + tetris->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); tetris->setStatic(); tetris->setId( TEXT_ID ); scene.addObject( tetris ); @@ -104,7 +107,7 @@ void addMainSceneItems( SDLPP::Scene &scene, auto next = std::make_shared< SDLPP::TextRenderer >( RIGHT_BORDER + 0.1, 0.35, 0.2, 0.1, r, "NEXT", g_font_config, SDLPP_TEXT_CENTER ); - next->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + next->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); next->setStatic(); next->setId( TEXT_ID ); scene.addObject( next ); @@ -123,7 +126,7 @@ void addMainSceneItems( SDLPP::Scene &scene, auto score_text = std::make_shared< SDLPP::TextRenderer >( RIGHT_BORDER + 0.1, 0.1, 0.2, 0.1, r, "SCORE", g_font_config, SDLPP_TEXT_CENTER ); - score_text->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + score_text->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); score_text->setStatic(); score_text->setId( TEXT_ID ); scene.addObject( score_text ); @@ -131,7 +134,7 @@ void addMainSceneItems( SDLPP::Scene &scene, auto score_texture = std::make_shared< SDLPP::TextRenderer >( RIGHT_BORDER + 0.1, 0.2, 0.2, 0.1, r, "0", g_font_config, SDLPP_TEXT_TOP ); - score_texture->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + score_texture->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); score_texture->setStatic(); score_texture->setId( SCORE_TEXTURE_ID ); scene.addObject( score_texture ); @@ -140,7 +143,7 @@ void addMainSceneItems( SDLPP::Scene &scene, LEFT_BORDER - 1, 0, 1, BOTTOM_BORDER, r ); border->setId( BORDER_LEFT_ID ); border->setStatic(); - border->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + border->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); border->addCollision( SDLPP::RectColider( 0, 0, 0.99, 1 ) ); border->setColiderColor( "#FF00FF" ); scene.addObject( border ); @@ -149,7 +152,7 @@ void addMainSceneItems( SDLPP::Scene &scene, BOTTOM_BORDER, r ); border->setId( BORDER_RIGHT_ID ); border->setStatic(); - border->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + border->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); border->addCollision( SDLPP::RectColider( 0.01, 0, 1, 1 ) ); border->setColiderColor( "#FF00FF" ); scene.addObject( border ); @@ -158,7 +161,7 @@ void addMainSceneItems( SDLPP::Scene &scene, LEFT_BORDER, BOTTOM_BORDER, RIGHT_BORDER - LEFT_BORDER, 1, r ); floor->setId( FLOOR_ID ); floor->setStatic(); - floor->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + floor->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); floor->addCollision( SDLPP::RectColider( 0, 0.01, 1, 1 ) ); floor->setColiderColor( "#00FF00" ); scene.addObject( floor ); @@ -174,37 +177,52 @@ void addMenuSceneItems( SDLPP::Scene &scene, auto y = std::make_shared< SDLPP::TextRenderer >( 0.25, 0.1, 0.5, 0.3, r ); y->setText( "PAUSED", g_font_config ); y->setId( MENU_TEXT_ID ); - y->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + y->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); scene.addObject( y ); auto resume = std::make_shared< SDLPP::TextRenderer >( 0.4, 0.46, 0.2, 0.08, r ); resume->setText( "Resume", g_font_config ); resume->setColor( colors["menu_item_background"] ); - resume->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + resume->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); resume->setId( MENU_ITEM_ID ); + resume->addCollision( + SDLPP::RectColider( { 0, 0 }, { 1, 1 }, MENU_RESUME_ID ) ); g_menu_options.push_back( resume ); scene.addObject( resume ); auto options = std::make_shared< SDLPP::TextRenderer >( 0.4, 0.56, 0.2, 0.08, r ); options->setText( "Options", g_font_config ); - options->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + options->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); options->setId( MENU_ITEM_ID ); + options->addCollision( + SDLPP::RectColider( { 0, 0 }, { 1, 1 }, MENU_OPTIONS_ID ) ); g_menu_options.push_back( options ); scene.addObject( options ); auto restart = std::make_shared< SDLPP::TextRenderer >( 0.4, 0.66, 0.2, 0.08, r ); restart->setText( "Restart", g_font_config ); - restart->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + restart->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); restart->setId( MENU_ITEM_ID ); + restart->addCollision( + SDLPP::RectColider( { 0, 0 }, { 1, 1 }, MENU_RESTART_ID ) ); g_menu_options.push_back( restart ); scene.addObject( restart ); auto quit = std::make_shared< SDLPP::TextRenderer >( 0.35, 0.76, 0.3, 0.08, r ); quit->setText( "Quit Game", g_font_config ); - quit->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + quit->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); quit->setId( MENU_ITEM_ID ); + quit->addCollision( + SDLPP::RectColider( { 0, 0 }, { 1, 1 }, MENU_QUIT_ID ) ); g_menu_options.push_back( quit ); scene.addObject( quit ); + auto mouse = + std::make_shared< SDLPP::RectangleRender >( 0.01, 0.01, 0.01, 0.01, r ); + mouse->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); + mouse->setId( MENU_MOUSE_ID ); + mouse->addCollision( + SDLPP::RectColider( { 0, 0 }, { 1, 1 } ) ); + scene.addObject( mouse ); } void addGameOverSceneItems( SDLPP::Scene &scene, @@ -217,12 +235,12 @@ void addGameOverSceneItems( SDLPP::Scene &scene, auto y = std::make_shared< SDLPP::TextRenderer >( 0.25, 0.1, 0.5, 0.3, r ); y->setText( "GAME OVER", g_font_config ); y->setId( 0 ); - y->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + y->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); scene.addObject( y ); auto restart = std::make_shared< SDLPP::TextRenderer >( 0.4, 0.5, 0.2, 0.1, r ); restart->setText( "Restart", g_font_config ); - restart->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + restart->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); restart->setColor( colors["menu_item_background"] ); restart->setId( MENU_ITEM_ID ); g_game_over_options.push_back( restart ); @@ -230,7 +248,7 @@ void addGameOverSceneItems( SDLPP::Scene &scene, auto quit = std::make_shared< SDLPP::TextRenderer >( 0.35, 0.7, 0.3, 0.1, r ); quit->setText( "Quit Game", g_font_config ); - quit->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + quit->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); quit->setId( MENU_ITEM_ID ); g_game_over_options.push_back( quit ); scene.addObject( quit ); @@ -246,39 +264,54 @@ void addOptionsSceneItems( SDLPP::Scene &scene, auto y = std::make_shared< SDLPP::TextRenderer >( 0.25, 0.1, 0.5, 0.3, r ); y->setText( "OPTIONS", g_font_config ); y->setId( 0 ); - y->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + y->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); scene.addObject( y ); auto color_scheme = std::make_shared< SDLPP::TextRenderer >( 0.18, 0.35, 0.64, 0.09, r ); color_scheme->setText( "Color scheme: " + color_schemes_names[selected_color_scheme], g_font_config ); - color_scheme->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + color_scheme->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); color_scheme->setColor( colors["menu_item_background"] ); color_scheme->setId( MENU_ITEM_ID ); + color_scheme->addCollision( + SDLPP::RectColider( { 0, 0 }, { 1, 1 }, OPTIONS_COLOR_ID ) ); g_options_options.push_back( color_scheme ); scene.addObject( color_scheme ); auto shadow = std::make_shared< SDLPP::TextRenderer >( 0.26, 0.45, 0.48, 0.09, r ); shadow->setText( "Show shadow: YES", g_font_config ); - shadow->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + shadow->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); shadow->setId( MENU_ITEM_ID ); + shadow->addCollision( + SDLPP::RectColider( { 0, 0 }, { 1, 1 }, OPTIONS_SHADOW_ID ) ); g_options_options.push_back( shadow ); scene.addObject( shadow ); auto show3d = std::make_shared< SDLPP::TextRenderer >( 0.2, 0.55, 0.6, 0.09, r ); show3d->setText( "Show block texture: NO", g_font_config ); - show3d->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + show3d->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); show3d->setId( MENU_ITEM_ID ); + show3d->addCollision( + SDLPP::RectColider( { 0, 0 }, { 1, 1 }, OPTIONS_3D_ID ) ); g_options_options.push_back( show3d ); scene.addObject( show3d ); auto save = std::make_shared< SDLPP::TextRenderer >( 0.42, 0.65, 0.16, 0.09, r ); save->setText( "SAVE", g_font_config ); - save->setAlignment(SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER); + save->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); save->setId( MENU_ITEM_ID ); + save->addCollision( + SDLPP::RectColider( { 0, 0 }, { 1, 1 }, OPTIONS_SAVE_ID ) ); g_options_options.push_back( save ); scene.addObject( save ); + auto mouse = + std::make_shared< SDLPP::RectangleRender >( 0.01, 0.01, 0.01, 0.01, r ); + mouse->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); + mouse->setId( MENU_MOUSE_ID ); + mouse->addCollision( + SDLPP::RectColider( { 0, 0 }, { 1, 1 } ) ); + scene.addObject( mouse ); } std::shared_ptr< SDLPP::Scene > @@ -552,6 +585,56 @@ void handleKeyDownMenu( SDL_Keycode key ) { } } +bool g_mouse_down = false; +int selected_menu_down = -1; +int selected_options_down = -1; + +void highlightMenuItem(uint64_t id) { + g_menu_options[g_menu_select]->unsetColor(); + switch(id) { + case MENU_RESUME_ID: + g_menu_select = 0; + break; + case MENU_OPTIONS_ID: + g_menu_select = 1; + break; + case MENU_RESTART_ID: + g_menu_select = 2; + break; + case MENU_QUIT_ID: + g_menu_select = 3; + default: + break; + } + if(g_mouse_down) + return; + g_menu_options[g_menu_select]->setColor( + colors["menu_item_background"] ); +} + +void highlightOptionsItem(uint64_t id) { + g_options_options[g_options_select]->unsetColor(); + switch(id) { + case OPTIONS_COLOR_ID: + g_options_select = 0; + break; + case OPTIONS_SHADOW_ID: + g_options_select = 1; + break; + case OPTIONS_3D_ID: + g_options_select = 2; + break; + case OPTIONS_SAVE_ID: + g_options_select = 3; + default: + break; + } + if(g_mouse_down) + return; + g_options_options[g_options_select]->setColor( + colors["menu_item_background"] ); +} + void pollEventsMenu() { SDL_Event event; while ( SDLPP::getSDLEvent( event ) ) { @@ -569,6 +652,30 @@ void pollEventsMenu() { g_update_scenes.push_back( x ); g_update_size = true; } + break; + case SDL_MOUSEMOTION: { + auto mouse = g_menu_scene->getObjects({MENU_MOUSE_ID})[0]; + mouse->setPos(SDLPP::Mouse::getMousePositionDouble(g_menu_scene->getRenderer(), SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER)); + auto collisions = g_menu_scene->getCollisions(*mouse); + if(collisions.size() == 2) { + for(auto &collision : collisions) { + if(collision.second->getId() == MENU_ITEM_ID) { + highlightMenuItem(collision.second->getCollisions()[0]->getId()); + } + } + } + } + break; + case SDL_MOUSEBUTTONUP: + g_mouse_down = false; + if(selected_menu_down == g_menu_select) { + handleKeyDownMenu(SDLK_RETURN); + } + break; + case SDL_MOUSEBUTTONDOWN: + g_mouse_down = true; + selected_menu_down = g_menu_select; + break; default: break; } @@ -794,6 +901,31 @@ void pollEventsOptions() { g_update_scenes.push_back( x ); g_update_size = true; } + break; + case SDL_MOUSEMOTION: { + auto mouse = g_options_scene->getObjects({MENU_MOUSE_ID})[0]; + mouse->setPos(SDLPP::Mouse::getMousePositionDouble(g_options_scene->getRenderer(), SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER)); + auto collisions = g_options_scene->getCollisions(*mouse); + if(collisions.size() == 2) { + for(auto &collision : collisions) { + if(collision.second->getId() == MENU_ITEM_ID) { + highlightOptionsItem(collision.second->getCollisions()[0]->getId()); + } + } + } + } + break; + case SDL_MOUSEBUTTONUP: + g_mouse_down = false; + if(selected_options_down == g_options_select) { + handleKeyDownOptions(SDLK_RIGHT); + handleKeyDownOptions(SDLK_RETURN); + } + break; + case SDL_MOUSEBUTTONDOWN: + g_mouse_down = true; + selected_options_down = g_options_select; + break; default: break; }