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