TETRIS: fix rotation
This commit is contained in:
parent
a10f3cf47e
commit
c7f5e834bb
140
tetris.cpp
140
tetris.cpp
@ -8,8 +8,9 @@
|
||||
#define BRICK_ID 0x00000002
|
||||
#define GAME_OVER 0x00000003
|
||||
#define SHADOW_ID 0x00000004
|
||||
#define BORDER_ID 0x00000005
|
||||
#define FLOOR_ID 0x00000006
|
||||
#define BORDER_LEFT_ID 0x00000005
|
||||
#define BORDER_RIGHT_ID 0x00000006
|
||||
#define FLOOR_ID 0x00000007
|
||||
|
||||
#define LEFT_BORDER 0.3
|
||||
#define RIGHT_BORDER 0.7
|
||||
@ -553,7 +554,7 @@ void addStuff( SDLPP::Scene &scene, std::shared_ptr< SDLPP::Renderer > &r ) {
|
||||
scene.addObject( shadow_colider );
|
||||
|
||||
auto border = std::make_shared< SDLPP::RectangleRender >( LEFT_BORDER - 1, TOP_BORDER, 1, BOTTOM_BORDER, r);
|
||||
border->setId( BORDER_ID );
|
||||
border->setId( BORDER_LEFT_ID );
|
||||
border->setStatic();
|
||||
border->centerX();
|
||||
border->addCollision(SDLPP::Rect( 0, 0, 0.99, 1));
|
||||
@ -561,7 +562,7 @@ void addStuff( SDLPP::Scene &scene, std::shared_ptr< SDLPP::Renderer > &r ) {
|
||||
scene.addObject(border);
|
||||
|
||||
border = std::make_shared< SDLPP::RectangleRender >( RIGHT_BORDER, TOP_BORDER, 1, BOTTOM_BORDER, r);
|
||||
border->setId( BORDER_ID );
|
||||
border->setId( BORDER_RIGHT_ID );
|
||||
border->setStatic();
|
||||
border->centerX();
|
||||
border->addCollision(SDLPP::Rect( 0.01, 0, 1, 1));
|
||||
@ -645,86 +646,67 @@ void quitGame() {
|
||||
quit = true;
|
||||
}
|
||||
|
||||
int crashFlags( std::shared_ptr<TetrisPiece> piece, std::shared_ptr<TetrisBlock> block, SDLPP::Scene &scene, int left, int right, int bottom) {
|
||||
int retFlags = 0;
|
||||
auto collisions = scene.getCollisions(*block, {BORDER_LEFT_ID, BORDER_RIGHT_ID, FLOOR_ID});
|
||||
for(auto &col : collisions) {
|
||||
switch(col->getId()) {
|
||||
case BORDER_LEFT_ID:
|
||||
retFlags |= left;
|
||||
break;
|
||||
case BORDER_RIGHT_ID:
|
||||
retFlags |= right;
|
||||
break;
|
||||
case FLOOR_ID:
|
||||
retFlags |= right;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
collisions = scene.getCollisions(*block, {BRICK_ID});
|
||||
if(collisions.size() > 1) {
|
||||
for(auto &col : collisions) {
|
||||
if(piece->isLeft(*col))
|
||||
retFlags |= left;
|
||||
else if(piece->isRight(*col))
|
||||
retFlags |= right;
|
||||
else
|
||||
retFlags |= bottom;
|
||||
}
|
||||
}
|
||||
return retFlags;
|
||||
}
|
||||
|
||||
bool checkRotation( std::shared_ptr<TetrisPiece> piece, SDLPP::Scene &scene ) {
|
||||
bool ret = true;
|
||||
bool crash = true;
|
||||
int left = 0x01;
|
||||
int right = 0x02;
|
||||
int bottom = 0x04;
|
||||
int flags = 0;
|
||||
// game board limits
|
||||
while ( crash ) {
|
||||
crash = false;
|
||||
flags = 0;
|
||||
for ( auto &block : piece->getObjects() ) {
|
||||
auto pos = block->getPos();
|
||||
if ( pos.first < LEFT_BORDER - 0.01 ) {
|
||||
flags |= left;
|
||||
crash = true;
|
||||
break;
|
||||
} else if ( pos.first > RIGHT_BORDER - BLOCK_SIZE + 0.01 ) {
|
||||
crash = true;
|
||||
flags |= right;
|
||||
break;
|
||||
} else if ( pos.second >= BOTTOM_BORDER ) {
|
||||
crash = true;
|
||||
flags |= bottom;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( crash ) {
|
||||
if ( flags & bottom || (flags & left && flags & right) ) {
|
||||
piece->revert();
|
||||
ret = false;
|
||||
} else {
|
||||
if( flags & left )
|
||||
piece->movePiece(BLOCK_SIZE, 0);
|
||||
else if( flags & right )
|
||||
piece->movePiece(-BLOCK_SIZE, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
int crash = 0;
|
||||
int cur_left = 0x01;
|
||||
int cur_right = 0x02;
|
||||
int was_left = 0x04;
|
||||
int was_right = 0x08;
|
||||
int bottom = 0x10;
|
||||
do {
|
||||
crash = 0;
|
||||
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);
|
||||
}
|
||||
crash |= crashFlags(piece, block, scene, cur_left, cur_right, bottom);
|
||||
}
|
||||
if(!crash)
|
||||
break;
|
||||
if((is_left && is_right) || (is_left && was_right) || (is_right && was_left)) {
|
||||
if(crash & bottom || (crash & cur_left && crash & cur_right) ||
|
||||
(crash & cur_left && crash & was_right) || (crash & cur_right && crash & was_left)) {
|
||||
piece->revert();
|
||||
ret = false;
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
was_left = is_left;
|
||||
was_right = is_right;
|
||||
if(is_left)
|
||||
crash &= ~(was_left | was_right);
|
||||
if(crash & cur_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();
|
||||
ret = false;
|
||||
break;
|
||||
crash &= ~cur_left;
|
||||
crash |= was_left;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
if(crash & cur_right) {
|
||||
piece->movePiece(-BLOCK_SIZE, 0);
|
||||
crash &= ~cur_right;
|
||||
crash |= was_right;
|
||||
}
|
||||
} while(crash);
|
||||
return true;
|
||||
}
|
||||
|
||||
void updateShadow(SDLPP::Scene &scene) {
|
||||
@ -758,9 +740,7 @@ void updateShadow(SDLPP::Scene &scene) {
|
||||
bool validPos(SDLPP::Scene &scene, std::shared_ptr<TetrisPiece> piece) {
|
||||
auto ret = true;
|
||||
for ( auto &x : piece->getObjects() ) {
|
||||
if(x->getId() != 2)
|
||||
std::cout << "ID: " << x->getId() << std::endl;
|
||||
auto collisions = scene.getCollisions( *x, { BRICK_ID, FLOOR_ID, BORDER_ID } );
|
||||
auto collisions = scene.getCollisions( *x, { BRICK_ID, FLOOR_ID, BORDER_LEFT_ID, BORDER_RIGHT_ID } );
|
||||
if ( collisions.size() > 1 ) {
|
||||
ret = false;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user