From 96c54454f7808550e4249ab55bda30c158ae184f Mon Sep 17 00:00:00 2001 From: zvon Date: Sun, 13 Sep 2020 14:14:39 +0200 Subject: [PATCH] TETRIS: Code cleanup --- tetris/Makefile | 2 +- tetris/functions.cpp | 59 +++++++++++++++++++++++------------------- tetris/global_vars.cpp | 1 - tetris/global_vars.hpp | 1 - tetris/scenes.cpp | 36 ++++++++++++++++---------- tetris/tetris.cpp | 12 +++++++-- 6 files changed, 66 insertions(+), 45 deletions(-) diff --git a/tetris/Makefile b/tetris/Makefile index 99a937c..751cf44 100644 --- a/tetris/Makefile +++ b/tetris/Makefile @@ -1,5 +1,5 @@ CXX ?= g++ -CFLAGS ?= -O2 -Wall -Wextra -g +CFLAGS ?= -O2 -Wall -Wextra PREFIX ?= /usr/local/bin LDFLAGS ?= -lSDL2 -lSDL2_image -lSDL2_gfx -lSDL2_ttf -pthread diff --git a/tetris/functions.cpp b/tetris/functions.cpp index c0988fa..dd41c16 100644 --- a/tetris/functions.cpp +++ b/tetris/functions.cpp @@ -5,15 +5,12 @@ #include bool validPos(SDLPP::Scene &scene, std::shared_ptr piece) { - auto ret = true; for ( auto &x : piece->getObjects() ) { auto collisions = scene.getCollisions( *x, { BRICK_ID, FLOOR_ID, BORDER_LEFT_ID, BORDER_RIGHT_ID } ); - if ( collisions.size() > 1 ) { - ret = false; - break; - } + if ( collisions.size() > 1 ) + return false; } - return ret; + return true; } void updateShadow(SDLPP::Scene &scene) { @@ -22,47 +19,46 @@ void updateShadow(SDLPP::Scene &scene) { g_cur_shadow.reset(); return; } + if(!g_cur_shadow) + return; g_cur_shadow->setPos(g_cur_object->getPos()); double shadow_drop = BOTTOM_BORDER; auto &invalid_objects = g_cur_object->getObjects(); for( auto &x : g_cur_shadow->getObjects() ) { - if(BOTTOM_BORDER - x->getPos().second < shadow_drop) - shadow_drop = BOTTOM_BORDER - x->getPos().second; - g_shadow_colider->setPos(x->getPos().first, TOP_BORDER); + auto block_pos = x->getPos(); + if(BOTTOM_BORDER - block_pos.second < shadow_drop) + shadow_drop = BOTTOM_BORDER - block_pos.second; + // set colider column's position to current block's X position + g_shadow_colider->setPos(block_pos.first, TOP_BORDER); auto collisions = scene.getCollisions( *g_shadow_colider, { BRICK_ID } ); - auto curY = x->getPos().second; + auto curY = block_pos.second; for(auto &col : collisions) { - auto colY = col->getPos().second; + // if collision with g_cur_object, ignore if(std::find(invalid_objects.begin(), invalid_objects.end(), col) != invalid_objects.end()) continue; - auto possible_drop = colY - curY; + auto possible_drop = col->getPos().second - curY; if(possible_drop < shadow_drop && possible_drop >= 0) - shadow_drop = colY - curY; + shadow_drop = possible_drop; } } + // we want the shadow to rest on top of the nearest floor shadow_drop -= BLOCK_SIZE; - g_cur_shadow->setPos(g_cur_shadow->getPos().first, g_cur_shadow->getPos().second + shadow_drop); + auto shadow_pos = g_cur_shadow->getPos(); + g_cur_shadow->setPos(shadow_pos.first, shadow_pos.second + shadow_drop); } void moveThem( std::shared_ptr< SDLPP::Scene > scene, int ticks ) { if ( !g_cur_object ) return; + // get movement generated by player auto movement = g_cur_object->getMovement(); + g_ticks_till_fall -= ticks; if ( g_cur_object->isDescending() ) g_ticks_till_descend -= ticks; if ( g_cur_object->isMoving() ) g_ticks_till_movement -= ticks; if ( g_ticks_till_fall > 0 ) { - if ( g_cur_object->isDescending() && g_ticks_till_descend <= 0 ) { - g_ticks_till_descend = TICKS_TILL_DESCEND; - g_cur_object->movePiece(0, movement.second * BLOCK_SIZE); - if(!validPos(*scene, g_cur_object)) { - g_cur_object->movePiece(0, movement.second * -BLOCK_SIZE); - return; - } else - goto check_floor; - } if ( g_cur_object->isMoving() && g_ticks_till_movement <= 0 ) { g_ticks_till_movement = TICKS_TILL_MOVE; g_cur_object->movePiece(movement.first * BLOCK_SIZE, 0); @@ -72,6 +68,15 @@ void moveThem( std::shared_ptr< SDLPP::Scene > scene, int ticks ) { } else goto check_floor; } + if ( g_cur_object->isDescending() && g_ticks_till_descend <= 0 ) { + g_ticks_till_descend = TICKS_TILL_DESCEND; + g_cur_object->movePiece(0, movement.second * BLOCK_SIZE); + if(!validPos(*scene, g_cur_object)) { + g_cur_object->movePiece(0, movement.second * -BLOCK_SIZE); + return; + } else + goto check_floor; + } return; } g_ticks_till_fall = TICKS_TILL_FALL; @@ -80,6 +85,7 @@ check_floor: bool fell = false; for ( auto &x : g_cur_object->getObjects() ) { auto collisions = scene->getCollisions( *x, { BRICK_ID, FLOOR_ID } ); + // we get 1 collision every time with ourselves if ( collisions.size() > 1 ) { fell = true; break; @@ -89,7 +95,6 @@ check_floor: g_cur_object->movePiece(0, -BLOCK_SIZE); for ( auto &block : g_cur_object->getObjects() ) { if ( scene->getCollisions( *block, { GAME_OVER } ).size() > 0 ) { - g_pause = PAUSE_GAME_OVER; g_game_over_scene->updateSizeAndPosition(); g_active_scenes.push_back( g_game_over_scene ); g_input_functions.push_back(gameOverSceneInput); @@ -107,7 +112,6 @@ void quitGame() { } void resetGame() { - g_pause = 0; g_cur_object.reset(); g_checked_line = true; g_next_object.reset(); @@ -116,12 +120,15 @@ void resetGame() { g_main_scene->resetScene(); g_main_scene->setPrevTicks( SDL_GetTicks() ); + // TODO maybe move to main thread 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_active_scenes.push_back( g_main_scene ); g_active_scenes = {g_main_scene}; g_input_functions = {mainSceneInput}; + for(int i = 0; i < 7; i++) + g_bag[i] = 28; } int crashFlags( std::shared_ptr piece, std::shared_ptr block, SDLPP::Scene &scene, int left, int right, int bottom) { @@ -136,7 +143,7 @@ int crashFlags( std::shared_ptr piece, std::shared_ptr retFlags |= right; break; case FLOOR_ID: - retFlags |= right; + retFlags |= bottom; default: break; } diff --git a/tetris/global_vars.cpp b/tetris/global_vars.cpp index 197cd19..67e97a0 100644 --- a/tetris/global_vars.cpp +++ b/tetris/global_vars.cpp @@ -5,7 +5,6 @@ int g_ticks_till_fall = TICKS_TILL_FALL; int g_ticks_till_descend = TICKS_TILL_DESCEND; int g_ticks_till_movement = TICKS_TILL_MOVE; -int g_pause = 0; int g_menu_select = 0; int g_menu_max = 3; diff --git a/tetris/global_vars.hpp b/tetris/global_vars.hpp index d8c37aa..f0d0a00 100644 --- a/tetris/global_vars.hpp +++ b/tetris/global_vars.hpp @@ -9,7 +9,6 @@ extern int g_ticks_till_fall; extern int g_ticks_till_descend; extern int g_ticks_till_movement; -extern int g_pause; extern int g_menu_select; extern int g_menu_max; diff --git a/tetris/scenes.cpp b/tetris/scenes.cpp index 111f4df..3883d4e 100644 --- a/tetris/scenes.cpp +++ b/tetris/scenes.cpp @@ -269,7 +269,6 @@ std::shared_ptr prepareOptionsScene(std::shared_ptrupdateSizeAndPosition(); g_active_scenes.push_back( g_menu_scene ); g_input_functions.push_back(menuSceneInput); @@ -281,7 +280,8 @@ void handleKeyDownMain( SDL_Keycode key, SDLPP::Scene &scene ) { g_cur_object->movePiece(-BLOCK_SIZE, 0); if(!validPos(scene, g_cur_object)) g_cur_object->movePiece(BLOCK_SIZE, 0); - updateShadow(scene); + else + updateShadow(scene); g_ticks_till_movement = 2*TICKS_TILL_MOVE; g_cur_object->startMovement(); @@ -294,7 +294,8 @@ void handleKeyDownMain( SDL_Keycode key, SDLPP::Scene &scene ) { g_cur_object->movePiece(BLOCK_SIZE, 0); if(!validPos(scene, g_cur_object)) g_cur_object->movePiece(-BLOCK_SIZE, 0); - updateShadow(scene); + else + updateShadow(scene); g_ticks_till_movement = 2*TICKS_TILL_MOVE; g_cur_object->startMovement(); @@ -304,6 +305,7 @@ void handleKeyDownMain( SDL_Keycode key, SDLPP::Scene &scene ) { case SDLK_s: if(!g_cur_object) break; + g_ticks_till_descend = 0; g_cur_object->startDescend(); g_cur_object->addMovement(0,1); break; @@ -321,9 +323,11 @@ void handleKeyDownMain( SDL_Keycode key, SDLPP::Scene &scene ) { break; g_cur_object->setPos(g_cur_shadow->getPos()); break; +#ifdef DEBUG case SDLK_r: scene.getRenderer().setRenderColiders( !scene.getRenderer().getRenderColiders() ); +#endif default: break; } @@ -338,7 +342,6 @@ void handleKeyUpMain( SDL_Keycode key ) { if(g_cur_object->isDescending()) { g_cur_object->stopDescend(); g_cur_object->addMovement(0,-1); - g_ticks_till_descend = TICKS_TILL_DESCEND; } break; case SDLK_LEFT: @@ -348,8 +351,6 @@ void handleKeyUpMain( SDL_Keycode key ) { if(g_cur_object->isMoving()) { g_cur_object->stopMovement(); g_cur_object->addMovement(1,0); - if(g_cur_object->isMoving()) - g_ticks_till_movement = TICKS_TILL_MOVE; } break; case SDLK_RIGHT: @@ -359,8 +360,6 @@ void handleKeyUpMain( SDL_Keycode key ) { if(g_cur_object->isMoving()) { g_cur_object->stopDescend(); g_cur_object->addMovement(-1,0); - if(g_cur_object->isMoving()) - g_ticks_till_movement = TICKS_TILL_MOVE; } default: break; @@ -429,15 +428,16 @@ void mainSceneInput( std::shared_ptr< SDLPP::Scene > scene, int base, std::vecto void handleKeyDownMenu( SDL_Keycode key ) { switch ( key ) { case SDLK_ESCAPE: { - g_pause = 0; g_main_scene->setPrevTicks( SDL_GetTicks() ); g_active_scenes.pop_back(); g_input_functions.pop_back(); } break; +#ifdef DEBUG case SDLK_r: g_main_scene->getRenderer().setRenderColiders( !g_main_scene->getRenderer().getRenderColiders() ); break; +#endif case SDLK_s: case SDLK_DOWN: g_menu_options[g_menu_select]->unsetColor(); @@ -455,15 +455,14 @@ void handleKeyDownMenu( SDL_Keycode key ) { g_menu_options[g_menu_select]->setColor( colors["menu_item_background"] ); break; case SDLK_RETURN: + // TODO maybe define macros for these switch ( g_menu_select ) { case 0: { - g_pause = 0; g_main_scene->setPrevTicks( SDL_GetTicks() ); g_active_scenes.pop_back(); g_input_functions.pop_back(); } break; case 1: - g_pause = PAUSE_PAUSE; g_options_scene->updateSizeAndPosition(); g_active_scenes.push_back(g_options_scene); g_input_functions.push_back(optionsSceneInput); @@ -509,10 +508,12 @@ void menuSceneInput( std::shared_ptr< SDLPP::Scene > /*UNUSED*/, int /*UNUSED*/, void handleKeyDownGameOver( SDL_Keycode key ) { switch ( key ) { +#ifdef DEBUG case SDLK_r: g_main_scene->getRenderer().setRenderColiders( !g_main_scene->getRenderer().getRenderColiders() ); break; +#endif case SDLK_s: case SDLK_DOWN: g_game_over_options[g_game_over_select]->unsetColor(); @@ -530,6 +531,7 @@ void handleKeyDownGameOver( SDL_Keycode key ) { g_game_over_options[g_game_over_select]->setColor( colors["menu_item_background"] ); break; case SDLK_RETURN: + //TODO maybe define macros for these switch ( g_game_over_select ) { case 0: resetGame(); @@ -574,18 +576,17 @@ void saveOptions() { g_update_colors = true; if(g_cur_shadow) g_cur_shadow->setHidden(!g_show_shadow); - g_pause = 0; g_main_scene->setPrevTicks( SDL_GetTicks() ); - g_active_scenes.pop_back(); - g_input_functions.pop_back(); } void handleKeyDownOptions( SDL_Keycode key ) { switch ( key ) { +#ifdef DEBUG case SDLK_r: g_main_scene->getRenderer().setRenderColiders( !g_main_scene->getRenderer().getRenderColiders() ); break; +#endif case SDLK_s: case SDLK_DOWN: g_options_options[g_options_select]->unsetColor(); @@ -604,6 +605,7 @@ void handleKeyDownOptions( SDL_Keycode key ) { break; case SDLK_RIGHT: case SDLK_d: + //TODO define macros switch( g_options_select ) { case 0: selected_color_scheme++; @@ -622,6 +624,7 @@ void handleKeyDownOptions( SDL_Keycode key ) { break; case SDLK_LEFT: case SDLK_a: + //TODO define macros switch( g_options_select ) { case 0: if(selected_color_scheme == 0) @@ -639,9 +642,12 @@ void handleKeyDownOptions( SDL_Keycode key ) { } break; case SDLK_RETURN: + //TODO define macros switch ( g_options_select ) { case 2: saveOptions(); + g_active_scenes.pop_back(); + g_input_functions.pop_back(); break; default: break; @@ -649,6 +655,8 @@ void handleKeyDownOptions( SDL_Keycode key ) { break; case SDLK_ESCAPE: saveOptions(); + g_active_scenes.pop_back(); + g_input_functions.pop_back(); default: break; } diff --git a/tetris/tetris.cpp b/tetris/tetris.cpp index 45e6081..564c06b 100644 --- a/tetris/tetris.cpp +++ b/tetris/tetris.cpp @@ -89,21 +89,29 @@ int main() { SDL_framerateDelay( &gFPS ); if ( !g_cur_object && g_checked_line ) { std::lock_guard< std::mutex > guard( g_movement_mutex ); + 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++; - if ( retries == 7 ) - quitGame(); + // 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 );