basic collision detection

Started by
52 comments, last by cwl157 15 years, 10 months ago
i have been working on this since 8 am this morning and have not gotten any farther. Can someone please tell me how i would do collisions. I dont care how many functions i have to write or anything i just need it figured out its driving me crazy. I have a function that places the piece on the board and i have a function that erases the piece from the board. To move a piece from the top to the bottom i create the piece then erase the piece then create the piece 1 down and then erase that piece and create it again 1 more down, i need to do this until it reaches the bottom. It detects the piece from the top and stops all of them when they get to a row above the bottom row. So the square is the only one that works because it is shaped like this:
22
22

The long piece vertically is this at the beginning:
1
1
1
1
and the bottom is not detected until it gets here at the end
1
1
again it stops it one row up from the bottom row.

the horizontal long piece looks like this to start:
1111
and ends like this:
1111
00000000

again one row above the bottom. How can i draw and erase shapes until it reaches a collision whether it be at the bottom or if there are already pieces down it would be above that and then i need it for the right and left as well.

Thank you
Advertisement
I have not read all the posts in great detail, but why do you ever need to erase shapes?

Also, how are your pieces represented?
well erase shapes to move them down. All my pieces are 2d int arrays so like a long line would look like:

vertical: Horizontal
1000 1111
1000 0000
1000 0000
1000 0000

the square is:
2200
2200
0000
0000

To move a shape i have a create function for each shape so to create the square i have a createSquare function that takes the x and y position of where the square will go it looks like this:

// create the square
void createSquare(int xPos, int yPos)
{
for (int row = 0; row < 4; row++)
{
for (int col = 0; col < 4; col++)
{
if (square[row][col] == 2)
gameBoard[row+yPos][col+xPos] = 2;
else
continue;
} // end for
} // end for
} // end createSquare

Now to move the square down the game board i create the shape at the top then erase that shape and create it again after incrementing the y position so its one down from where it used to be. To move the shape right i erase the shape increment the x position 1 and recreate the shape with the new x position so its 1 to the right. To erase i just have an eraseSquare function that is the same as createSquare but instead of changing from 0 to 2 it changes from 2 to 0.

So basically i have 2 problems. Like the long line vertical for example, i start detecting from the 1st 1 not the last so the collision isnt detected until it gets to 1 from the top because thats the y position its using to compare, i need to use the bottom most 1. I need to figure that problem out and with setting the other board after that is detected because it goes create, erase, increment create erase increment so the last thing is erasing and then i try and set the game board array equal to the array that holds set pieces and it does not work right because the board ends with the piece erased.
First, the shape movement can be much simpler. Suppose that you have a variable posY that tracks the shape's vertical position. Instead of constantly copying the shape to the board and erasing it, just check to see if the shape collides with the board. If it does, copy the shape to the board at position posY - 1. Otherwise, increment posY by 1.

In other words, moving the shape simply means updating a couple of variables that hold the shape's current position. Only after you've detected that the shape collides with the board, you copy it to the board.

Second, I don't understand why the collision detection doesn't work if you start testing the shape's individual squares from the top. Why does it matter if you start testing from the top or the bottom?
i start at the top and create and erase them all the way down to the bottom then when i get to the bottom it does not detect that its at the bottom until the first block gets there because thats the one that i pass to the collision test function. Also what do you mean collides with the board? Like the int at that position on the board is 0 and then draw just that 1 block and not the whole piece? Also how would i draw the whole shape using this method i would be jumping all over the x and y position as it moves down and then if the whole shape has to move left or right... i don't get how that works. But if i had collision detection functions for each shape then when that shape is the one being moved i could just call those collision detection functions until a down collision is detected then x and y are reset and the next shape is drawn at the top. I think i would still have a problem with the create and erase thing though.
There is no need to have a separate collision detection function for each shape.

If I understand you correctly, each shape is represented as a 4x4 array where 0 represents an empty space. Also, the board is represented as a large 2D array in a similar way.

Given these representations, a check for collision simply means testing if the shape, in it's current position, overlaps with the board.

The code should look something like this:

bool checkCollision(int posX, int posY){    for (int r = 0; r < 4; ++r)        for (int c = 0; c < 4; ++c)        {            if ( (board[r+posY][c+posX] != 0) && (shape[r][c] != 0) )                // There's overlap                return true;        }    return false;} 


Here's how moving the shape down might be handled:

int posX = 0, posY = 0;    // Holds the shape's positionif (down key pressed)    if (checkCollision(posX, posY))        copyShapeToBoard(posX, posY-1);    else        ++posY;


Of course, both code samples are meant to be illustrative and probably don't take some things into consideration.

EDIT: Actually the second code snippet is wrong because the shape should move down even if no key is pressed. Pressing the down key should only make it move faster, but that is not important to what I was trying to illustrate.

I have to go now but if you have any more questions, I'll try to reply tomorrow.

[Edited by - Gage64 on June 21, 2008 11:08:04 PM]
ok, the collision function you posted worked but each shape array is different therefore, wouldn't i need a collision detection function for each shape?
The function Gage64 posted should work with every shape. If the shape overlaps with the board, then there is a collision, if it doesn't overlap, then there is no collision. It doesn't matter what the shape looks like.
Quote:Original post by cwl157
ok, the collision function you posted worked but each shape array is different therefore, wouldn't i need a collision detection function for each shape?


No. Notice that a shape is just an array where some entries are 0 and some are not. The values of the other entries do not matter. All that matters is that they are not 0.

What makes two shapes different is the location of the non-zero entries, but the collision detection function doesn't care where those entries are - it goes over all entries in the shape. Therefore, it will work with every type of shape.
what gets me is in his function he compares an array called shape to check if its equal to zero. I have a different 2d int array for each shape so then does it not matter which shape array i use to compare? I think since i have a different 2d int array for each shape dont i have to have a different collision function for each shape that uses the shape's 2d int array?

This topic is closed to new replies.

Advertisement