Tetris Collision Detection

Started by
10 comments, last by kontrolkl 18 years, 2 months ago
Up until now I've been able to get through game programming with a basic square against square collision detection which works great (or at least good enough for what I've needed so far). Since I'm probably the only person that hasn't made his own Tetris Clone, I thought I'd get started on that. I'm working on a 2D Tetris Clone using C++ and DirectX. If it were just made up of the square and straight line pieces, this would be too easy, but it's not. Those little 'L' shapes, the Backwards L shapes, and the other Tent looking piece require a more sophisticated form of collision detection. I was hoping that someone here could help lead me towards a solution to this problem. Though I didn't specifically explain the problem, I'm sure anyone who's been there, knows what I'm talking about. Thanks a bunch.
Advertisement
I once made a 3d-tetris (2d-tetris that you could rotate, silly idea though :) ) and I simply had a bool-matrix which was true at the positions where there was a part of a piece and false otherwise. Before moving the piece down or sideways I make sure that the "coast was clear". To do this you need some kind of model of how the board/pieces look like, maybe if you have a matrix for the piece-objects as well, like:
0000 x0000000 x0000x00 x000xxx0 x000
etc. At least that's the first thing that comes to my mind.
Just for the record, I havent made a tetris clone. [smile]

About the collision detection, it hasnt to be so hard, does it? Make the entire play area an array of integers (then one value for every color, 0 for black/empty) then just drop the peices one tile downwards until one of the tiles under it is not black/empty.

Of course, youll have to come up with a way to store the the current peice thats moving. A vector with all coords the peice takes up maybe? Then when you move it, make every tile the peice occupies black, add 1 to every Y coordinate in the peices of the peice (:P) vector, and redraw it there.

I use this code in my Asteroids clone. I figure if it works for complex polygons, it should work for your shapes. Here, x0 and y0 are the center of the polygon. I suppose you would have to modify this to work for whatever structures you're using, but maybe it will get you started? Good luck.

int Collision_Test(const POLYGON2D &polygon1, POLYGON2D &polygon2){// this function tests if the two polygons overlapint x1,y1, x2,y2, dy1, dy2;x1 = polygon1.x0 ;y1 = polygon1.y0 ;x2 = polygon2.x0 ;y2 = polygon2.y0 ;dy1 = 0 ; dy2 = 0 ; int distance = sqrt( (x1-x2) * (x1-x2) + (y1+dy1-y2+dy2) * (y1+dy1-y2+dy2)) ;if (distance <= (polygon1.width / 2) + (polygon2.width / 2) ||	distance <= (polygon1.height / 2) + (polygon2.height / 2) )	return (1) ;return (0) ;}
That's all very good stuff! Thanks for time and thoughts. :-)
I'm currently writing a Tetris "clone" in J2ME, to get all the specs down, and this is what my collision algorithm looks like.

* currShape[][] is a 4x4 matrix containing the current shape
* currShapeX / currShapeY are the x / y id's in the "board" matrix
* board[][] is the 10x18 game board, pretty obious =)
* BOARD_HEIGHT / BOARD_WIDTH are 18 and 10 respectively
boolean CurrShapeColliding(){    for(int i = 0; i < 4; ++i)        for(int j = 0; j < 4; ++j)            // if shape contains block on i-j, check against board            if(currShape[j] == 1)            {                // check pos range!                if((currShapeX + j < 0 || currShapeX + j >= BOARD_WIDTH) || (currShapeY + i >= BOARD_HEIGHT))                {                    // piece is out of bounds, collision with wall                    return true;                }                else                {                    // don't go outside board matrix                    if(currShapeY + i >= 0)                         if(board[currShapeY + i][currShapeX + j] == 1)                             // block-block collision!                             return true;                }            }    return false;}

Yes it uses "box" collision (well, in a way), but that's enough for Tetris, since every shape is built of 4 boxes. =)
----------------------------------------------------------------------------------------------------------------------"Ask not what humanity can do for you, ask what you can do for humanity." - By: Richard D. Colbert Jr.
The purpose of making a Tetris clone is to learn how a game works. To get the most out of your experience, you should really work through challenges like this on your own (or for a bigger project with your team).

I did a Tetris clone last fall and had the same challenge. After collision detection with straight and square pieces worked, it only took another couple of hours to get it working with the Z and L pieces.

If you want, you can download all of the source code to many different Tetris clones on the internet, see how someone else did it, have them hold your hand, but I would really try to work through it first. You will feel much better about the end result.

Good luck.

Phil

Yup, my "2 hour production ascii tetris" game I made here a while back basically did this:

set up an array for the board something like [15][25]

when a brick lands add each portion of the brick to the board

the main loop would drop the brick down if the proper amount of time had passed (proper amount of time determined by what level you were on) if it tried to drop the brick down and there was any portion of the brick that would overlap a board array that had somethign in it, instead of dropping the brick it would add the brick to the board array and reset the brick object's location to the top and get a random type.

If the player tried to rotate the brick it would do the rotation, check to see if any part overlapped with a filled board position or if any part would be out of bounds (left, right, or bottom of the screen) and would flip back before drawing if it detected an overlap.

The player could press down to make the brick instantly drop down a position. If this happened, simply run the same check that I previously mentioned before dropping the brick.

The piece itself was set up as a 4x4 array with an x and y position which indicated where on the board the top left corner of the array mapped to. The piece could then be flipped by simply iterating through it differently. No actual rotation needed, just iterate through the array differently and save the results and the object would flip.
_______________________"You're using a screwdriver to nail some glue to a ming vase. " -ToohrVyk
Quote:
If you want, you can download all of the source code to many different Tetris clones on the internet, see how someone else did it, have them hold your hand, but I would really try to work through it first. You will feel much better about the end result.

IMHO, it's nothing wrong with downloading a source for something to get different views of how different people solved a certain problem, so you with that research can solve it your way. The end result would still be your own creation and you would still feel great about it.

On the other hand, to download source only to copy'n'paste it is a really bad ide, but since it sounded like the OP has given it some thought and was stuck, it would only be fair to give hime a few examples to get him started. =)
----------------------------------------------------------------------------------------------------------------------"Ask not what humanity can do for you, ask what you can do for humanity." - By: Richard D. Colbert Jr.
Hi, if you're stuck, you can download the source of some tetris clones, and there are some tutorials too. If you decide not to, then it can be a good idea anyway to look at them afterwards. It helped me to see how there are different solutions to the same problem.

A basic solution is to think of a tetris piece as composed of square blocks, which can be placed in a 4x4 array, as has been mentioned. What works for me generally, is to draw these things out. Just draw an array like this, then draw the rotated pieces and compare. It'll be much easier then to see the relation between the original piece and the desired piece. Try thinking less about code first and more about what will happen in the game. Decompose the problem in several steps. You have rotating without collision, checking if a rotation will result in a piece out of the board, against other pieces, on the bottom, etc. Solve them one by one.
Good luck.

This topic is closed to new replies.

Advertisement