Jump to content
  • Advertisement
Sign in to follow this  
cptrnet

Block rotation in tetris?

This topic is 4828 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I was wondering how I could rotate blocks in tetris. In my game right now I have rows and columns and each shape has blocks in different cols and rows. I was thinking I could just say move up two and over two or something. But what about the walls and other blocks. What makes it so the shape can or can't rotate? I mean what would be a good way of telling you can rotate sometimes but if its next to a wall or other block then it can't?

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
To rotate a piece you can rotate the position of each of the blocks it is made of seperately. First, express the position of each block relative to the one you want to rotate around. For example the block to the right of the one you're rotate around would have position (x, y) = (1, 0). Then the rotated position of the block would be (y, -x), or a rotation in the other direction is (-y, x).

Which rotation is clock-wise and which is counter-clockwise depends on if y increases going up or down.

To test if the rotation is possible just check if the rotated posion of each block works or not. If the new position is outside the game field or on another block, don't allow the rotation.

If you want to derive the rotation stuff yourself try taking some equations for rotation or a rotation matrix and plug in 90 degrees.

Hope that helps.

Share this post


Link to post
Share on other sites
Well I've never made tertis (nor do I intend to [smile]) but if you imagine that a falling shape is comprised of blocks then each possible shape (if not randomly generated, but they usualy arent, so thats good) can be stored in a small 6x6 (or bigger) char array where each array element indicates the presense of a block and block colour(or 'color' if your american) to make up a shape.

OK, so to determine if a shape is touching (colliding) with any other blocks or the floor simply go through each block of the shape and compare it against each block on the screen (there are faster ways - thats the easiest but sadly the slowest method) and test if they touch (you might already have that bit sussed)

Now we can extend that system so that a shape is actually 4 such arrays of blocks - one array for each orientation - then when you want to rotate the shape just make sure that none of the blocks of the desired orientaion overlap with currently existing blocks.

This method has two advantages: 1- its easy to implement and 2- its flexible so you can have shape change shape when you rotate them which would be fun for the harder levels of your tetris :)

Hope that was some help :)

Share this post


Link to post
Share on other sites
My tetris game (that I didn't finish) stored each block as a 4x4 grid. Then I rotated inside of that grid:
xxxx
ooox
oooo
oooo

Would rotate to:
ooox
ooox
ooox
ooxx

Then to do colision I just checked against each node in the grid.

Share this post


Link to post
Share on other sites
On determining whether a block can rotate:

Check to see if the new rotated piece overlaps anything. If it does, start checking it at positions to the side of its current position. One block to the left, one block to the right. Two blocks left. Two blocks right. Stop checking as soon as it fits. If it doesnt fit anywhere within two blocks left or right it can't be rotated.

This is what I do in my tetris and it works great. You can also use it against the border of the game field, not just the blocks that are filled.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I would not try to programmatically rotate the blocks. It's not that it doesn't work, but it generally gives results that suck. Just pre-compute the coordinates of each block in each rotation and store them in an array.

If you think of all your pieces as relative to an upper-left corner, then manually rotate each block such that it stays flush with the top and left. Then as you move that reference point down, the block moves with.

your block would look like

____ _____ ____ ____
| o | o |ooo |o
|ooo |oo | o |oo
| | o | |o
| | | |

// store the (x,y) coordinates of each brick for each rotation:

int t_block[4][4][2] =
{ { {1,0}, {0,1}, {1,1}, {2,1} },
{ {1,0}, {0,1}, {1,1}, {1,2} },
{ {0,0}, {1,0}, {2,0}, {1,1} },
{ {0,0}, {0,1}, {1,1}, {0,2} },
};

// then to try to see whether you can rotate, or move the block down,
// just test whether the new position causes any of the bricks to occupy
// a space in the pit that is already occupied:

const int pit_width = 10;
const int pit_height = 20;

int pit[pit_width][pit_height] = { {0} };

int try_pos(int block_x, int block_y, int block_test[4][2], int pit[pit_width][pit_height])
{
for(int i = 0; i < 4; i++)
{
if(pit[block_x + block_test[0]][block_y + block_test[1]])
return false;
}
return true;
}

// the rest is easy.

int move_block_down()
{
if(try_pos(block_x, block_y + 1, block[cur_pos], pit))
block_y++;
else; // hit bottom
}

int rotate_block()
{
if(try_pos(block_x, block_y, block[(cur_pos + 1)%4], pit))
cur_pos = (cur_pos + 1) % 4;

// else rotation is blocked
}



the only exception to the flush top-left rule is the schlong block in its vertical position, where it should be in the x=2 column.

--ajas

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I have written a few tetris like games. When i made my first one i had exactly the same problem as you.

Then i realised that every tetris piece contains of four blocks. I used this to create a offset array for each block for each of the 4 rotations, so for the L, shape i have (Delphi):

Type TBrick = class
XOff : Array[1..4, 1..4] of Integer;
YOff : Array[1..4, 1..4] of Integer;
end;

Where the first dimension of the array is for the rotation and the second is for the offsets. I load all the information from files and then for rendering and collision detection all i need to do is use a simple for loop and test 4 times:


procedure TBrick.Render(XPos, YPos: Integer);
var Counter: Integer;
begin
brickTextures[ Piece.Texture ].Bind;

glPushMatrix();
glTranslatef(XPos, YPos, 0);
glScalef(BLOCK_SIZE, BLOCK_SIZE, 1);

glTranslatef(X-1, 20-Y, 0);
For Counter:=1 to 4 do begin
glPushMatrix();
glTranslatef(XOff[Orientation][Counter], -YOff[Orientation][Counter], 0);
glCallList( planeList );
glPopMatrix();
end;
glPopMatrix();
end;

.. and collision...

function TLevel.Colission(Brick: TBrick): Boolean;
var Counter: Integer;
var Element: TPoint;
begin
Result:=False;

For Counter:=1 to 4 do begin
Element:=Brick[Counter];

Result:=Result or (Level[ Element.X, Element.Y] 0);
end;

end;

Where Level is a 2 dimensional array discribing the level (borders and filled blocks)

/Andreaz - www.glxtreem.net


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!