2021-01-30 21:18:15 +00:00
|
|
|
#include "custom_classes.hpp"
|
|
|
|
|
|
|
|
std::shared_ptr< SDLPP::Texture > TetrisBlock::block_texture = nullptr;
|
2021-03-09 08:27:15 +00:00
|
|
|
#ifdef FEATURE
|
2021-03-13 17:37:23 +00:00
|
|
|
const std::vector< SDL_Rect > blockanim = { { 0, 0, 125, 125 },
|
|
|
|
{ 125, 0, 250, 125 },
|
|
|
|
{ 125, 125, 250, 250 },
|
|
|
|
{ 0, 125, 125, 250 } };
|
2021-03-09 08:27:15 +00:00
|
|
|
#endif
|
2021-01-30 21:18:15 +00:00
|
|
|
|
|
|
|
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();
|
2021-03-09 08:27:15 +00:00
|
|
|
if ( TetrisBlock::block_texture == nullptr ) {
|
2021-01-30 21:18:15 +00:00
|
|
|
TetrisBlock::block_texture =
|
|
|
|
std::make_shared< SDLPP::Texture >( renderer, "block.png" );
|
2021-03-13 17:37:23 +00:00
|
|
|
TetrisBlock::block_texture->setAlpha( 240 );
|
2021-03-09 08:27:15 +00:00
|
|
|
}
|
2021-01-30 21:18:15 +00:00
|
|
|
if ( g_show_3d )
|
2021-03-09 08:27:15 +00:00
|
|
|
#ifdef FEATURE
|
|
|
|
setTexture( TetrisBlock::block_texture, 0, 0, 125, 125 );
|
|
|
|
setAnimationFrames( blockanim );
|
2021-03-13 17:37:23 +00:00
|
|
|
setAnimationSpeed( 4 );
|
2021-03-09 08:27:15 +00:00
|
|
|
#else
|
2021-01-30 21:18:15 +00:00
|
|
|
setTexture( TetrisBlock::block_texture );
|
2021-03-09 08:27:15 +00:00
|
|
|
#endif
|
2021-01-30 21:18:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TetrisBlock::TetrisBlock( const TetrisBlock &other )
|
2021-03-12 21:33:46 +00:00
|
|
|
: TetrisBlock( other.getDoubleRect().first.getX(),
|
|
|
|
other.getDoubleRect().first.getY(),
|
|
|
|
other.getDoubleRect().second.getX(),
|
|
|
|
other.getDoubleRect().second.getY(), other.getRenderer(),
|
2021-01-30 21:18:15 +00:00
|
|
|
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();
|
2021-03-12 21:33:46 +00:00
|
|
|
auto diff1 = mypos.getX() - otherpos.getX();
|
2021-01-30 21:18:15 +00:00
|
|
|
diff1 = ( diff1 < 0 ) * ( -1 ) * diff1 + ( diff1 > 0 ) * diff1;
|
2021-03-12 21:33:46 +00:00
|
|
|
auto diff2 = mypos.getY() - otherpos.getY();
|
2021-01-30 21:18:15 +00:00
|
|
|
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();
|
2021-01-30 22:00:58 +00:00
|
|
|
// fallthrough
|
2021-01-30 21:18:15 +00:00
|
|
|
case PIECE_ACTION_UPDATE_BLOCK:
|
|
|
|
if ( g_show_3d )
|
2021-03-09 08:27:15 +00:00
|
|
|
#ifdef FEATURE
|
|
|
|
setTexture( TetrisBlock::block_texture, 0, 0, 125, 125 );
|
|
|
|
#else
|
|
|
|
setTexture( TetrisBlock::block_texture );
|
|
|
|
#endif
|
2021-01-30 21:18:15 +00:00
|
|
|
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];
|
2021-03-12 21:33:46 +00:00
|
|
|
auto piece_position = piece->getPos();
|
|
|
|
original_pos[i] = piece_position;
|
2021-03-13 17:37:23 +00:00
|
|
|
piece_position +=
|
|
|
|
{ positions[0] * BLOCK_SIZE - positions[1] * BLOCK_SIZE,
|
|
|
|
positions[2] * BLOCK_SIZE - positions[3] * BLOCK_SIZE };
|
2021-01-30 21:18:15 +00:00
|
|
|
auto bottom = positions[3];
|
|
|
|
auto top = positions[2];
|
|
|
|
positions[3] = positions[1];
|
|
|
|
positions[2] = positions[0];
|
|
|
|
positions[1] = top;
|
|
|
|
positions[0] = bottom;
|
2021-03-13 17:37:23 +00:00
|
|
|
piece_position +=
|
|
|
|
{ positions[1] * BLOCK_SIZE - positions[0] * BLOCK_SIZE,
|
|
|
|
positions[3] * BLOCK_SIZE - positions[2] * BLOCK_SIZE };
|
2021-03-12 21:33:46 +00:00
|
|
|
piece->setPos( piece_position );
|
2021-01-30 21:18:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TetrisPiece::revert() {
|
|
|
|
for ( unsigned long i = 0; i < pieces.size(); i++ ) {
|
|
|
|
auto &piece = pieces[i];
|
|
|
|
auto &positions = pieces_rel_position[i];
|
2021-03-12 21:33:46 +00:00
|
|
|
piece->setPos( original_pos[i] );
|
2021-01-30 21:18:15 +00:00
|
|
|
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 );
|
|
|
|
}
|
|
|
|
|
2021-03-13 17:37:23 +00:00
|
|
|
void TetrisPiece::setPos( const SDLPP::Vec2D< double > &vec ) {
|
2021-03-12 21:33:46 +00:00
|
|
|
setPos( vec.getX(), vec.getY() );
|
|
|
|
}
|
|
|
|
|
2021-03-13 17:37:23 +00:00
|
|
|
SDLPP::Vec2D< double > TetrisPiece::getPos() {
|
2021-01-30 21:18:15 +00:00
|
|
|
auto &piece = pieces[0];
|
|
|
|
auto &relpositions = pieces_rel_position[0];
|
|
|
|
auto pos = piece->getPos();
|
2021-03-12 21:33:46 +00:00
|
|
|
pos += { relpositions[0] * BLOCK_SIZE - relpositions[1] * BLOCK_SIZE,
|
|
|
|
relpositions[2] * BLOCK_SIZE - relpositions[3] * BLOCK_SIZE };
|
2021-01-30 21:18:15 +00:00
|
|
|
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();
|
2021-03-13 17:37:23 +00:00
|
|
|
block->setPos( pos + SDLPP::Vec2D< double >( x, y ) );
|
2021-01-30 21:18:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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 );
|
|
|
|
}
|