From 430d99ff38036bba39f233e54fdb230677670bb6 Mon Sep 17 00:00:00 2001 From: zv0n Date: Sat, 30 Jan 2021 22:18:15 +0100 Subject: [PATCH] TETRIS: Split custom_classes into cpp and hpp and only use 1 shared block texture --- tetris/Makefile | 4 +- tetris/custom_classes.cpp | 318 ++++++++++++++++++++++++++++++++++++++ tetris/custom_classes.hpp | 307 ++++++------------------------------ 3 files changed, 364 insertions(+), 265 deletions(-) create mode 100644 tetris/custom_classes.cpp diff --git a/tetris/Makefile b/tetris/Makefile index 4814ca5..eed71e6 100644 --- a/tetris/Makefile +++ b/tetris/Makefile @@ -16,7 +16,7 @@ LDFLAGS ?= -lSDL2 -lSDL2_image -lSDL2_gfx -lSDL2_ttf -pthread OUTPUTFLAG = -o endif -TETRIS_OBJECTS = tetris.${OBJEXT} scenes.${OBJEXT} config.${OBJEXT} functions.${OBJEXT} global_vars.${OBJEXT} +TETRIS_OBJECTS = tetris.${OBJEXT} scenes.${OBJEXT} config.${OBJEXT} functions.${OBJEXT} global_vars.${OBJEXT} custom_classes.${OBJEXT} ifeq ($(UNAME_S),Linux) TETRIS_OBJECTS += libsdlpp.so @@ -51,6 +51,8 @@ functions.${OBJEXT}: functions.cpp config.hpp functions.hpp global_vars.hpp scen $(CXX) $(CXXFLAGS) -c ${OUTPUTFLAG}$@ $< global_vars.${OBJEXT}: global_vars.cpp config.hpp global_vars.hpp functions.hpp $(CXX) $(CXXFLAGS) -c ${OUTPUTFLAG}$@ $< +custom_classes.${OBJEXT}: custom_classes.cpp custom_classes.hpp + $(CXX) $(CXXFLAGS) -c ${OUTPUTFLAG}$@ $< libsdlpp.so: ../sdlpp $(MAKE) clean -C ../sdlpp $(MAKE) -C ../sdlpp diff --git a/tetris/custom_classes.cpp b/tetris/custom_classes.cpp new file mode 100644 index 0000000..e8465d7 --- /dev/null +++ b/tetris/custom_classes.cpp @@ -0,0 +1,318 @@ +#include "custom_classes.hpp" + +std::shared_ptr< SDLPP::Texture > TetrisBlock::block_texture = nullptr; + +TetrisBlock::TetrisBlock( double x, double y, double w, double h, + const std::shared_ptr< SDLPP::Renderer > &r, + const std::string &img_or_color, bool is_polygon, + int index, std::shared_ptr< SDLPP::Scene > scene, + std::vector< int > &bag ) + : RectangleRender( x, y, w, h, r, img_or_color, is_polygon ), + pieces_bag( bag ) { + _index = index; + pieces_bag[_index]--; + _scene = scene; + setColors(); + if ( TetrisBlock::block_texture == nullptr ) + TetrisBlock::block_texture = + std::make_shared< SDLPP::Texture >( renderer, "block.png" ); + if ( g_show_3d ) + setTexture( TetrisBlock::block_texture ); +} + +TetrisBlock::TetrisBlock( const TetrisBlock &other ) + : TetrisBlock( other.getDoubleRect().first.first, + other.getDoubleRect().first.second, + other.getDoubleRect().second.first, + other.getDoubleRect().second.second, other.getRenderer(), + other.getColor(), true, other._index, other._scene, + other.pieces_bag ) {} + +TetrisBlock::~TetrisBlock() { + if ( _index != PIECE_SHADOW ) + pieces_bag[_index]++; +} + +std::shared_ptr< SDLPP::RenderObject > TetrisBlock::copySelf() { + auto ret = std::make_shared< TetrisBlock >( *this ); + copyTo( ret ); + return ret; +} + +void TetrisBlock::copyTo( std::shared_ptr< SDLPP::RenderObject > other ) { + RectangleRender::copyTo( other ); +} + +std::shared_ptr< TetrisBlock > TetrisBlock::copyInScene() { + auto ret = std::shared_ptr< TetrisBlock >( new TetrisBlock( *this ) ); + _scene->addObject( ret ); + return ret; +} + +bool TetrisBlock::isSamePos( const SDLPP::RenderObject &other ) const { + auto mypos = getPos(); + auto otherpos = other.getPos(); + auto diff1 = mypos.first - otherpos.first; + diff1 = ( diff1 < 0 ) * ( -1 ) * diff1 + ( diff1 > 0 ) * diff1; + auto diff2 = mypos.second - otherpos.second; + diff2 = ( diff2 < 0 ) * ( -1 ) * diff2 + ( diff2 > 0 ) * diff2; + return diff1 < 0.0001 && diff2 < 0.0001; +} + +void TetrisBlock::specialAction( int code ) { + switch ( code ) { + case PIECE_ACTION_UPDATE_COLOR: + setColors(); + case PIECE_ACTION_UPDATE_BLOCK: + if ( g_show_3d ) + setTexture( "block.png" ); + else + unsetTexture(); + default: + break; + } +} + +void TetrisBlock::turnIntoShadow() { + setId( SHADOW_ID ); + // shadows don't consume pieces from bag + pieces_bag[_index]++; + _index = PIECE_SHADOW; + setColors(); +} + +std::string TetrisBlock::getPieceName() { + switch ( _index ) { + case PIECE_BRICK: + return "piece_brick"; + case PIECE_T: + return "piece_T"; + case PIECE_L_RIGHT: + return "piece_L_right"; + case PIECE_Z_RIGHT: + return "piece_Z_right"; + case PIECE_LINE: + return "piece_line"; + case PIECE_L_LEFT: + return "piece_L_left"; + case PIECE_Z_LEFT: + return "piece_Z_left"; + case PIECE_SHADOW: + return "shadow"; + default: + break; + } + return ""; +} + +void TetrisBlock::setColors() { + auto piece_name = getPieceName(); + setColor( colors[piece_name] ); + setOutlineColor( colors[piece_name + "_out"] ); +} + +TetrisPiece::TetrisPiece() { + original_pos.reserve( 4 ); +} + +void TetrisPiece::addPiece( std::shared_ptr< TetrisBlock > piece, int x, + int y ) { + pieces.push_back( piece ); + pieces_rel_position.push_back( { 0, 0, 0, 0 } ); + // done this way for SPEEEEEEED + // left + pieces_rel_position.back()[0] = ( x < 0 ) * ( -1 ) * x; + // right + pieces_rel_position.back()[1] = ( x > 0 ) * x; + // top + pieces_rel_position.back()[2] = ( y < 0 ) * ( -1 ) * y; + // bottom + pieces_rel_position.back()[3] = ( y > 0 ) * y; +} + +void TetrisPiece::rotate() { + if ( !rotate_allowed ) + return; + for ( unsigned long i = 0; i < pieces.size(); i++ ) { + auto &piece = pieces[i]; + auto &positions = pieces_rel_position[i]; + auto position = piece->getPos(); + original_pos[i] = position; + position.first += positions[0] * BLOCK_SIZE; + position.first -= positions[1] * BLOCK_SIZE; + position.second += positions[2] * BLOCK_SIZE; + position.second -= positions[3] * BLOCK_SIZE; + auto bottom = positions[3]; + auto top = positions[2]; + positions[3] = positions[1]; + positions[2] = positions[0]; + positions[1] = top; + positions[0] = bottom; + position.first -= positions[0] * BLOCK_SIZE; + position.first += positions[1] * BLOCK_SIZE; + position.second -= positions[2] * BLOCK_SIZE; + position.second += positions[3] * BLOCK_SIZE; + piece->setPos( position.first, position.second ); + } +} + +void TetrisPiece::revert() { + for ( unsigned long i = 0; i < pieces.size(); i++ ) { + auto &piece = pieces[i]; + auto &positions = pieces_rel_position[i]; + piece->setPos( original_pos[i].first, original_pos[i].second ); + auto top = positions[1]; + auto bottom = positions[0]; + positions[1] = positions[3]; + positions[0] = positions[2]; + positions[2] = top; + positions[3] = bottom; + } +} + +std::vector< std::shared_ptr< TetrisBlock > > &TetrisPiece::getObjects() { + return pieces; +} + +void TetrisPiece::setPos( double x, double y ) { + for ( unsigned long i = 0; i < pieces.size(); i++ ) { + auto &piece = pieces[i]; + auto &positions = pieces_rel_position[i]; + std::pair< double, double > pos = { x, y }; + pos.first -= positions[0] * BLOCK_SIZE; + pos.first += positions[1] * BLOCK_SIZE; + pos.second -= positions[2] * BLOCK_SIZE; + pos.second += positions[3] * BLOCK_SIZE; + piece->setPos( pos.first, pos.second ); + } +} + +void TetrisPiece::setPos( const std::pair< double, double > &pos ) { + setPos( pos.first, pos.second ); +} + +std::pair< double, double > TetrisPiece::getPos() { + auto &piece = pieces[0]; + auto &relpositions = pieces_rel_position[0]; + auto pos = piece->getPos(); + pos.first += relpositions[0] * BLOCK_SIZE; + pos.first -= relpositions[1] * BLOCK_SIZE; + pos.second += relpositions[2] * BLOCK_SIZE; + pos.second -= relpositions[3] * BLOCK_SIZE; + return pos; +} + +void TetrisPiece::clear() { + pieces.clear(); + pieces_rel_position.clear(); +} + +void TetrisPiece::startDescend() { + descend = true; +} + +void TetrisPiece::stopDescend() { + descend = false; +} + +void TetrisPiece::startMovement() { + userMovement += 1; +} + +void TetrisPiece::stopMovement() { + userMovement -= 1; +} + +bool TetrisPiece::isDescending() { + return descend; +} + +bool TetrisPiece::isMoving() { + return userMovement > 0; +} + +bool TetrisPiece::isLeft( const SDLPP::RenderObject &block ) const { + return isPosition( block, 0 ); +} + +bool TetrisPiece::isRight( const SDLPP::RenderObject &block ) const { + return isPosition( block, 1 ); +} + +void TetrisPiece::movePiece( double x, double y ) { + for ( auto &block : getObjects() ) { + auto pos = block->getPos(); + block->setPos( pos.first + x, pos.second + y ); + } +} + +void TetrisPiece::disableRotation() { + rotate_allowed = false; +} + +void TetrisPiece::turnIntoShadow() { + for ( auto &block : getObjects() ) + block->turnIntoShadow(); + setHidden( !g_show_shadow ); +} + +std::shared_ptr< TetrisPiece > TetrisPiece::copySelf() { + auto ret = std::make_shared< TetrisPiece >(); + for ( int i = 0; i < 4; i++ ) { + auto block = pieces[i]->copyInScene(); + block->centerX(); + ret->addBlockInPos( block, pieces_rel_position[i] ); + } + if ( !rotate_allowed ) + ret->disableRotation(); + ret->setHidden( _hidden ); + return ret; +} + +void TetrisPiece::destroy() { + for ( auto &x : getObjects() ) { + x->destroy(); + } +} + +void TetrisPiece::addMovement( int x, int y ) { + movement.first += x; + movement.second += y; +} + +std::pair< int, int > TetrisPiece::getMovement() const { + return movement; +} + +void TetrisPiece::setHidden( bool hidden ) { + _hidden = hidden; + for ( auto &x : getObjects() ) { + x->setHidden( hidden ); + } +} + +bool TetrisPiece::getHidden() { + return _hidden; +} + +bool TetrisPiece::isPosition( const SDLPP::RenderObject &block, + int pos ) const { + for ( int i = 0; i < 4; i++ ) { + if ( pieces[i]->isSamePos( block ) ) { + return pieces_rel_position[i][pos] != 0; + } + } + return false; +} + +void TetrisPiece::resetBlock( int index, + std::shared_ptr< TetrisBlock > piece ) { + piece->setPos( pieces[index]->getPos() ); + pieces[index] = piece; +} + +void TetrisPiece::addBlockInPos( std::shared_ptr< TetrisBlock > piece, + const std::vector< int > &relpos ) { + pieces.push_back( piece ); + pieces_rel_position.push_back( relpos ); +} diff --git a/tetris/custom_classes.hpp b/tetris/custom_classes.hpp index 2c7ccaf..28acd32 100644 --- a/tetris/custom_classes.hpp +++ b/tetris/custom_classes.hpp @@ -11,283 +11,62 @@ public: const std::shared_ptr< SDLPP::Renderer > &r, const std::string &img_or_color, bool is_polygon, int index, std::shared_ptr< SDLPP::Scene > scene, - std::vector< int > &bag ) - : RectangleRender( x, y, w, h, r, img_or_color, is_polygon ), - pieces_bag( bag ) { - _index = index; - pieces_bag[_index]--; - _scene = scene; - setColors(); - if ( g_show_3d ) - setTexture( "block.png" ); - } - TetrisBlock( const TetrisBlock &other ) - : TetrisBlock( other.getDoubleRect().first.first, - other.getDoubleRect().first.second, - other.getDoubleRect().second.first, - other.getDoubleRect().second.second, - other.getRenderer(), other.getColor(), true, - other._index, other._scene, other.pieces_bag ) {} - ~TetrisBlock() { - if ( _index != PIECE_SHADOW ) - pieces_bag[_index]++; - } - virtual std::shared_ptr< RenderObject > copySelf() override { - auto ret = std::make_shared< TetrisBlock >( *this ); - copyTo( ret ); - return ret; - } - virtual void copyTo( std::shared_ptr< RenderObject > other ) override { - RectangleRender::copyTo( other ); - } - std::shared_ptr< TetrisBlock > copyInScene() { - auto ret = std::shared_ptr< TetrisBlock >( new TetrisBlock( *this ) ); - _scene->addObject( ret ); - return ret; - } - bool isSamePos( const SDLPP::RenderObject &other ) const { - auto mypos = getPos(); - auto otherpos = other.getPos(); - auto diff1 = mypos.first - otherpos.first; - diff1 = ( diff1 < 0 ) * ( -1 ) * diff1 + ( diff1 > 0 ) * diff1; - auto diff2 = mypos.second - otherpos.second; - diff2 = ( diff2 < 0 ) * ( -1 ) * diff2 + ( diff2 > 0 ) * diff2; - return diff1 < 0.0001 && diff2 < 0.0001; - } - virtual void specialAction( int code ) override { - switch ( code ) { - case PIECE_ACTION_UPDATE_COLOR: - setColors(); - case PIECE_ACTION_UPDATE_BLOCK: - if ( g_show_3d ) - setTexture( "block.png" ); - else - unsetTexture(); - default: - break; - } - } - void turnIntoShadow() { - setId( SHADOW_ID ); - // shadows don't consume pieces from bag - pieces_bag[_index]++; - _index = PIECE_SHADOW; - setColors(); - } + std::vector< int > &bag ); + TetrisBlock( const TetrisBlock &other ); + ~TetrisBlock(); + virtual std::shared_ptr< RenderObject > copySelf() override; + virtual void copyTo( std::shared_ptr< RenderObject > other ) override; + std::shared_ptr< TetrisBlock > copyInScene(); + bool isSamePos( const SDLPP::RenderObject &other ) const; + virtual void specialAction( int code ) override; + void turnIntoShadow(); private: - std::string getPieceName() { - switch ( _index ) { - case PIECE_BRICK: - return "piece_brick"; - case PIECE_T: - return "piece_T"; - case PIECE_L_RIGHT: - return "piece_L_right"; - case PIECE_Z_RIGHT: - return "piece_Z_right"; - case PIECE_LINE: - return "piece_line"; - case PIECE_L_LEFT: - return "piece_L_left"; - case PIECE_Z_LEFT: - return "piece_Z_left"; - case PIECE_SHADOW: - return "shadow"; - default: - break; - } - return ""; - } - void setColors() { - auto piece_name = getPieceName(); - setColor( colors[piece_name] ); - setOutlineColor( colors[piece_name + "_out"] ); - } + std::string getPieceName(); + void setColors(); + int _index = 0; std::shared_ptr< SDLPP::Scene > _scene; std::vector< int > &pieces_bag; + static std::shared_ptr< SDLPP::Texture > block_texture; }; class TetrisPiece { public: - TetrisPiece() { - original_pos.reserve( 4 ); - } - void addPiece( std::shared_ptr< TetrisBlock > piece, int x, int y ) { - pieces.push_back( piece ); - pieces_rel_position.push_back( { 0, 0, 0, 0 } ); - // done this way for SPEEEEEEED - // left - pieces_rel_position.back()[0] = ( x < 0 ) * ( -1 ) * x; - // right - pieces_rel_position.back()[1] = ( x > 0 ) * x; - // top - pieces_rel_position.back()[2] = ( y < 0 ) * ( -1 ) * y; - // bottom - pieces_rel_position.back()[3] = ( y > 0 ) * y; - } - void rotate() { - if ( !rotate_allowed ) - return; - for ( unsigned long i = 0; i < pieces.size(); i++ ) { - auto &piece = pieces[i]; - auto &positions = pieces_rel_position[i]; - auto position = piece->getPos(); - original_pos[i] = position; - position.first += positions[0] * BLOCK_SIZE; - position.first -= positions[1] * BLOCK_SIZE; - position.second += positions[2] * BLOCK_SIZE; - position.second -= positions[3] * BLOCK_SIZE; - auto bottom = positions[3]; - auto top = positions[2]; - positions[3] = positions[1]; - positions[2] = positions[0]; - positions[1] = top; - positions[0] = bottom; - position.first -= positions[0] * BLOCK_SIZE; - position.first += positions[1] * BLOCK_SIZE; - position.second -= positions[2] * BLOCK_SIZE; - position.second += positions[3] * BLOCK_SIZE; - piece->setPos( position.first, position.second ); - } - } - void revert() { - for ( unsigned long i = 0; i < pieces.size(); i++ ) { - auto &piece = pieces[i]; - auto &positions = pieces_rel_position[i]; - piece->setPos( original_pos[i].first, original_pos[i].second ); - auto top = positions[1]; - auto bottom = positions[0]; - positions[1] = positions[3]; - positions[0] = positions[2]; - positions[2] = top; - positions[3] = bottom; - } - } - std::vector< std::shared_ptr< TetrisBlock > > &getObjects() { - return pieces; - } - void setPos( double x, double y ) { - for ( unsigned long i = 0; i < pieces.size(); i++ ) { - auto &piece = pieces[i]; - auto &positions = pieces_rel_position[i]; - std::pair< double, double > pos = { x, y }; - pos.first -= positions[0] * BLOCK_SIZE; - pos.first += positions[1] * BLOCK_SIZE; - pos.second -= positions[2] * BLOCK_SIZE; - pos.second += positions[3] * BLOCK_SIZE; - piece->setPos( pos.first, pos.second ); - } - } - void setPos( const std::pair< double, double > &pos ) { - setPos( pos.first, pos.second ); - } - std::pair< double, double > getPos() { - auto &piece = pieces[0]; - auto &relpositions = pieces_rel_position[0]; - auto pos = piece->getPos(); - pos.first += relpositions[0] * BLOCK_SIZE; - pos.first -= relpositions[1] * BLOCK_SIZE; - pos.second += relpositions[2] * BLOCK_SIZE; - pos.second -= relpositions[3] * BLOCK_SIZE; - return pos; - } - void clear() { - pieces.clear(); - pieces_rel_position.clear(); - } - void startDescend() { - descend = true; - } - void stopDescend() { - descend = false; - } - void startMovement() { - userMovement += 1; - } - void stopMovement() { - userMovement -= 1; - } - bool isDescending() { - return descend; - } - bool isMoving() { - return userMovement > 0; - } - bool isLeft( const SDLPP::RenderObject &block ) const { - return isPosition( block, 0 ); - } - bool isRight( const SDLPP::RenderObject &block ) const { - return isPosition( block, 1 ); - } - void movePiece( double x, double y ) { - for ( auto &block : getObjects() ) { - auto pos = block->getPos(); - block->setPos( pos.first + x, pos.second + y ); - } - } - void disableRotation() { - rotate_allowed = false; - } + TetrisPiece(); + void addPiece( std::shared_ptr< TetrisBlock > piece, int x, int y ); + void rotate(); + void revert(); + std::vector< std::shared_ptr< TetrisBlock > > &getObjects(); + void setPos( double x, double y ); + void setPos( const std::pair< double, double > &pos ); + std::pair< double, double > getPos(); + void clear(); + void startDescend(); + void stopDescend(); + void startMovement(); + void stopMovement(); + bool isDescending(); + bool isMoving(); + bool isLeft( const SDLPP::RenderObject &block ) const; + bool isRight( const SDLPP::RenderObject &block ) const; + void movePiece( double x, double y ); + void disableRotation(); - void turnIntoShadow() { - for ( auto &block : getObjects() ) - block->turnIntoShadow(); - setHidden( !g_show_shadow ); - } - std::shared_ptr< TetrisPiece > copySelf() { - auto ret = std::make_shared< TetrisPiece >(); - for ( int i = 0; i < 4; i++ ) { - auto block = pieces[i]->copyInScene(); - block->centerX(); - ret->addBlockInPos( block, pieces_rel_position[i] ); - } - if ( !rotate_allowed ) - ret->disableRotation(); - ret->setHidden( _hidden ); - return ret; - } - void destroy() { - for ( auto &x : getObjects() ) { - x->destroy(); - } - } - void addMovement( int x, int y ) { - movement.first += x; - movement.second += y; - } - std::pair< int, int > getMovement() const { - return movement; - } - void setHidden( bool hidden ) { - _hidden = hidden; - for ( auto &x : getObjects() ) { - x->setHidden( hidden ); - } - } - bool getHidden() { - return _hidden; - } + void turnIntoShadow(); + std::shared_ptr< TetrisPiece > copySelf(); + void destroy(); + void addMovement( int x, int y ); + std::pair< int, int > getMovement() const; + void setHidden( bool hidden ); + bool getHidden(); private: - bool isPosition( const SDLPP::RenderObject &block, int pos ) const { - for ( int i = 0; i < 4; i++ ) { - if ( pieces[i]->isSamePos( block ) ) { - return pieces_rel_position[i][pos] != 0; - } - } - return false; - } - void resetBlock( int index, std::shared_ptr< TetrisBlock > piece ) { - piece->setPos( pieces[index]->getPos() ); - pieces[index] = piece; - } + bool isPosition( const SDLPP::RenderObject &block, int pos ) const; + void resetBlock( int index, std::shared_ptr< TetrisBlock > piece ); void addBlockInPos( std::shared_ptr< TetrisBlock > piece, - const std::vector< int > &relpos ) { - pieces.push_back( piece ); - pieces_rel_position.push_back( relpos ); - } + const std::vector< int > &relpos ); + std::vector< std::vector< int > > pieces_rel_position; std::vector< std::shared_ptr< TetrisBlock > > pieces; std::vector< std::pair< double, double > > original_pos;