Check surroundings before rotation
This commit is contained in:
parent
9daf4b373d
commit
e6bf3def99
138
tetris.cpp
138
tetris.cpp
@ -58,6 +58,15 @@ public:
|
|||||||
~TetrisBlock() {
|
~TetrisBlock() {
|
||||||
bag[_index]++;
|
bag[_index]++;
|
||||||
}
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _index = 0;
|
int _index = 0;
|
||||||
@ -68,7 +77,7 @@ public:
|
|||||||
TetrisPiece() {
|
TetrisPiece() {
|
||||||
original_pos.reserve( 4 );
|
original_pos.reserve( 4 );
|
||||||
}
|
}
|
||||||
void addPiece( std::shared_ptr< SDLPP::RectangleRender > piece, int x,
|
void addPiece( std::shared_ptr< TetrisBlock > piece, int x,
|
||||||
int y ) {
|
int y ) {
|
||||||
pieces.push_back( piece );
|
pieces.push_back( piece );
|
||||||
pieces_rel_position.push_back( { 0, 0, 0, 0 } );
|
pieces_rel_position.push_back( { 0, 0, 0, 0 } );
|
||||||
@ -110,7 +119,7 @@ public:
|
|||||||
pieces[i]->setPos( original_pos[i].first, original_pos[i].second );
|
pieces[i]->setPos( original_pos[i].first, original_pos[i].second );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::vector< std::shared_ptr< SDLPP::RectangleRender > > &getObjects() {
|
std::vector< std::shared_ptr< TetrisBlock > > &getObjects() {
|
||||||
return pieces;
|
return pieces;
|
||||||
}
|
}
|
||||||
void setPos( double x, double y ) {
|
void setPos( double x, double y ) {
|
||||||
@ -139,10 +148,30 @@ public:
|
|||||||
bool isDescending() {
|
bool isDescending() {
|
||||||
return descend;
|
return descend;
|
||||||
}
|
}
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
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;
|
||||||
|
}
|
||||||
std::vector< std::vector< int > > pieces_rel_position;
|
std::vector< std::vector< int > > pieces_rel_position;
|
||||||
std::vector< std::shared_ptr< SDLPP::RectangleRender > > pieces;
|
std::vector< std::shared_ptr< TetrisBlock > > pieces;
|
||||||
std::vector< std::pair< double, double > > original_pos;
|
std::vector< std::pair< double, double > > original_pos;
|
||||||
double default_x;
|
double default_x;
|
||||||
double default_y;
|
double default_y;
|
||||||
@ -159,7 +188,7 @@ bool quit = false;
|
|||||||
|
|
||||||
std::mutex movement_mutex;
|
std::mutex movement_mutex;
|
||||||
|
|
||||||
std::shared_ptr< SDLPP::RectangleRender >
|
std::shared_ptr< TetrisBlock >
|
||||||
createTetrisBlock( double x, double y, const std::string &color,
|
createTetrisBlock( double x, double y, const std::string &color,
|
||||||
const std::string &outline, int index,
|
const std::string &outline, int index,
|
||||||
std::shared_ptr< SDLPP::Renderer > renderer,
|
std::shared_ptr< SDLPP::Renderer > renderer,
|
||||||
@ -459,6 +488,7 @@ void checkRotation( std::shared_ptr<TetrisPiece> piece, SDLPP::Scene &scene ) {
|
|||||||
int right = 0x02;
|
int right = 0x02;
|
||||||
int bottom = 0x04;
|
int bottom = 0x04;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
// game board limits
|
||||||
while ( crash ) {
|
while ( crash ) {
|
||||||
crash = false;
|
crash = false;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
@ -482,18 +512,49 @@ void checkRotation( std::shared_ptr<TetrisPiece> piece, SDLPP::Scene &scene ) {
|
|||||||
if ( flags == bottom ) {
|
if ( flags == bottom ) {
|
||||||
piece->revert();
|
piece->revert();
|
||||||
} else {
|
} else {
|
||||||
for ( auto &block : piece->getObjects() ) {
|
if( flags == left )
|
||||||
auto pos = block->getPos();
|
piece->movePiece(BLOCK_SIZE, 0);
|
||||||
switch ( flags ) {
|
else if( flags == right )
|
||||||
case 1:
|
piece->movePiece(-BLOCK_SIZE, 0);
|
||||||
block->setPos( pos.first + BLOCK_SIZE, pos.second );
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// blocks
|
||||||
|
crash = true;
|
||||||
|
bool was_left = false;
|
||||||
|
bool was_right = false;
|
||||||
|
bool is_left = false;
|
||||||
|
bool is_right = false;
|
||||||
|
while ( crash ) {
|
||||||
|
is_left = false;
|
||||||
|
is_right = false;
|
||||||
|
crash = false;
|
||||||
|
for(auto &block : piece->getObjects()) {
|
||||||
|
auto collisions = scene.getCollisions(*block, {BRICK_ID});
|
||||||
|
if(collisions.size() == 1)
|
||||||
|
continue;
|
||||||
|
for(auto &col : collisions) {
|
||||||
|
crash = true;
|
||||||
|
is_left |= piece->isLeft(*col);
|
||||||
|
is_right |= piece->isRight(*col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!crash)
|
||||||
break;
|
break;
|
||||||
case 2:
|
if((is_left && is_right) || (is_left && was_right) || (is_right && was_left)) {
|
||||||
block->setPos( pos.first - BLOCK_SIZE, pos.second );
|
piece->revert();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
was_left = is_left;
|
||||||
}
|
was_right = is_right;
|
||||||
|
if(is_left)
|
||||||
|
piece->movePiece(BLOCK_SIZE, 0);
|
||||||
|
if(is_right)
|
||||||
|
piece->movePiece(-BLOCK_SIZE, 0);
|
||||||
|
// either bottom or up
|
||||||
|
if(!is_left && !is_right) {
|
||||||
|
piece->revert();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -512,49 +573,32 @@ void handleKeyDown( SDL_Keycode key, SDLPP::Scene &scene ) {
|
|||||||
case SDLK_a:
|
case SDLK_a:
|
||||||
if(!cur_object)
|
if(!cur_object)
|
||||||
break;
|
break;
|
||||||
for ( auto &x : cur_object->getObjects() ) {
|
cur_object->movePiece(-BLOCK_SIZE, 0);
|
||||||
auto pos = x->getPos();
|
|
||||||
// 0.01 because doubles
|
|
||||||
if ( pos.first < ( LEFT_BORDER + 0.01 ) )
|
|
||||||
crash = true;
|
|
||||||
x->setPos( pos.first - BLOCK_SIZE, pos.second );
|
|
||||||
}
|
|
||||||
for ( auto &x : cur_object->getObjects() ) {
|
for ( auto &x : cur_object->getObjects() ) {
|
||||||
auto collisions = scene.getCollisions( *x, { BRICK_ID } );
|
auto collisions = scene.getCollisions( *x, { BRICK_ID } );
|
||||||
if ( collisions.size() > 1 )
|
auto pos = x->getPos();
|
||||||
|
if ( collisions.size() > 1 || pos.first < ( LEFT_BORDER - 0.01 ) )
|
||||||
crash = true;
|
crash = true;
|
||||||
}
|
}
|
||||||
if ( crash ) {
|
if ( crash )
|
||||||
for ( auto &x : cur_object->getObjects() ) {
|
cur_object->movePiece(BLOCK_SIZE, 0);
|
||||||
auto pos = x->getPos();
|
|
||||||
x->setPos( pos.first + BLOCK_SIZE, pos.second );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case SDLK_RIGHT:
|
case SDLK_RIGHT:
|
||||||
case SDLK_d:
|
case SDLK_d:
|
||||||
if(!cur_object)
|
if(!cur_object)
|
||||||
break;
|
break;
|
||||||
for ( auto &x : cur_object->getObjects() ) {
|
cur_object->movePiece(BLOCK_SIZE, 0);
|
||||||
auto pos = x->getPos();
|
|
||||||
// 0.01 because doubles
|
|
||||||
if ( pos.first > RIGHT_BORDER - BLOCK_SIZE - 0.01 ) {
|
|
||||||
crash = true;
|
|
||||||
}
|
|
||||||
x->setPos( pos.first + BLOCK_SIZE, pos.second );
|
|
||||||
}
|
|
||||||
for ( auto &x : cur_object->getObjects() ) {
|
for ( auto &x : cur_object->getObjects() ) {
|
||||||
auto collisions = scene.getCollisions( *x, { BRICK_ID } );
|
auto collisions = scene.getCollisions( *x, { BRICK_ID } );
|
||||||
if ( collisions.size() > 1 ) {
|
auto pos = x->getPos();
|
||||||
|
if ( collisions.size() > 1 || pos.first > RIGHT_BORDER - BLOCK_SIZE + 0.01 ) {
|
||||||
crash = true;
|
crash = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( crash ) {
|
if ( crash )
|
||||||
for ( auto &x : cur_object->getObjects() ) {
|
cur_object->movePiece(-BLOCK_SIZE, 0);
|
||||||
auto pos = x->getPos();
|
|
||||||
x->setPos( pos.first - BLOCK_SIZE, pos.second );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case SDLK_DOWN:
|
case SDLK_DOWN:
|
||||||
case SDLK_s:
|
case SDLK_s:
|
||||||
@ -688,10 +732,7 @@ void moveThem( std::shared_ptr< SDLPP::Scene > scene, int ticks ) {
|
|||||||
}
|
}
|
||||||
ticks_till_fall = TICKS_TILL_FALL;
|
ticks_till_fall = TICKS_TILL_FALL;
|
||||||
fall:
|
fall:
|
||||||
for ( auto &x : cur_object->getObjects() ) {
|
cur_object->movePiece(0, BLOCK_SIZE);
|
||||||
auto pos = x->getPos();
|
|
||||||
x->setPos( pos.first, pos.second + BLOCK_SIZE );
|
|
||||||
}
|
|
||||||
bool fell = false;
|
bool fell = false;
|
||||||
for ( auto &x : cur_object->getObjects() ) {
|
for ( auto &x : cur_object->getObjects() ) {
|
||||||
auto collisions = scene->getCollisions( *x, { BRICK_ID } );
|
auto collisions = scene->getCollisions( *x, { BRICK_ID } );
|
||||||
@ -705,10 +746,7 @@ fall:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( fell ) {
|
if ( fell ) {
|
||||||
for ( auto &x : cur_object->getObjects() ) {
|
cur_object->movePiece(0, -BLOCK_SIZE);
|
||||||
auto pos = x->getPos();
|
|
||||||
x->setPos( pos.first, pos.second - BLOCK_SIZE );
|
|
||||||
}
|
|
||||||
for ( auto &block : cur_object->getObjects() ) {
|
for ( auto &block : cur_object->getObjects() ) {
|
||||||
if ( scene->getCollisions( *block, { GAME_OVER } ).size() > 0 ) {
|
if ( scene->getCollisions( *block, { GAME_OVER } ).size() > 0 ) {
|
||||||
std::cout << "You lost" << std::endl;
|
std::cout << "You lost" << std::endl;
|
||||||
|
Loading…
Reference in New Issue
Block a user