Skip to main content
gamedev.net
🔒 Locked

Tetris Clone Problem

Started by ov3r_dr1v3 Sep 4, 2008 at 9:30 AM 0 replies 1.1k views
Original Post
ov3r_dr1v3
ov3r_dr1v3
Hello, I've been developing a Tetris clone, which I'm having a bit of a problem with, and so hopefully looking for some advice. The problem I'm having is that seemingly randomly a tetris piece will stop moving down as if it has hit the bottom of the grid, when it is only half way down and should be able to keep moving. Here is the section of code which is responsible for moving the Tetris piece down every second or so(depending on the current level). Just to make things a bit clearer...here a tetris piece consists of 4 Tetris Blocks. The position of a Tetris Piece is the centre of a 4x4 grid in which the piece is contained. And the position of a Tetris block is the centre of its square.

	if(!paused)
	{
		DWORD time = GetTickCount();		

		int lines = 0;						

		if((time - last_time) > (1000/level))		
		{		
			if(canPieceMoveDown(&piece))	// Check to see if it is possible for the piece to move down
			{
				piece.UpdatePosition(Vector2f(piece.getPosition().x, piece.getPosition().y - 50));	// If the piece can move down then move it down 
			}
			else	
			{
				cout << "Cannot Move Down" << endl;
				TetrisBlock* blocks = piece.getBlocks();					// the 4 blocks in the current piece
				for(int b = 0; b < 4; b++)									// Loop through all 4 blocks in the active piece	
				{
					_blocks.push_back(blocks);							// and add each block to the list of stationary blocks

					int grid_posx = (int)(blocks.getPosition().x/50);			
					int grid_posy = (int)(blocks.getPosition().y/50);	// Store the grid position of the current block being looped through

					grid[grid_posx][grid_posy].block = &blocks
				}

				AddPiece();				
				lines = CheckForCompletedLine();	// Check for any completed lines
			}

			last_time = time;		// Reset the last time
		}

		for(int i = 0; i < _blocks.size(); i++)								// Loop through all blocks
		{
			if(!(lowest_comp_line == -1))									// check if a line has been completed  
			{
				int g_posx = (int)(_blocks.getPosition().x/50);			
				int g_posy = (int)(_blocks.getPosition().y/50);			// Store the grid position of the current block being looped through

				if(g_posy >= lowest_comp_line)								// Move block down by the number of completed lines nly if it is above the lines completed
				{
					_blocks.at(i).setPosition(Vector2f(_blocks.at(i).getPosition().x, _blocks.at(i).getPosition().y - (lines*50)));
				}
				
			}
			_blocks.at(i).Draw(50, texMan);			// Draw all of the stationary blocks
		}
	}

As you can see from this the method canPieceMoveDown() takes a pointer to a tetris piece and returns true if it can move down, and false if it cant(if it is going out of bounds, or there is a tetris block in the way). Here is my method for determing whether a piece an move down or not.

bool TetrisGrid::canPieceMoveDown(TetrisPiece* p)
{
	bool canMove = true;
	bool b0belowEmpty = true; bool b1belowEmpty = true; bool b2belowEmpty = true; bool b3belowEmpty = true;

	TetrisBlock* blocks = p->getBlocks();

	for(int a = 0; a < 4; a++)											// Loop through all 4 blocks in the active piece	
	{
		int grid_posx = (int)(blocks[a].getPosition().x/50);			
		int grid_posy = (int)(blocks[a].getPosition().y/50);			// Store the grid position of the current block being looped through

		Vector2f block_grid_pos = getGridPosition(blocks[a].getPosition());

		cout << "Block Position " << blocks[a].getPosition().x << " " << blocks[a].getPosition().y << endl;
		cout << "Block " << a << " " << block_grid_pos.x << " " << block_grid_pos.y << endl << endl;
		
		if(!((grid_posy - 1) >= 0))										// check if the block is not going out of bounds			
		{
			canMove = false;											// Once one of the pieces cannot move down past the bottom of the tetris grid	
			return false;
		}																// none of them can, so return false
		else if(grid[grid_posx][grid_posy - 1].occupied)						// Now check if the block can move to the grid position below
		{
			canMove = false;											// The grid position below is occupied	

			for(int c = 0; c < 4; c++)									// Loop through the other blocks in the piece and make sure that the block that occupied the cell
			{															// below is not part of the same piece
				int t_grid_posx = (int)(blocks[c].getPosition().x/50);			
				int t_grid_posy = (int)(blocks[c].getPosition().y/50);	// Store the grid position of the current block being looped through

				if(((grid_posy - 1) == t_grid_posy) && (grid_posx == t_grid_posx))
				{
					canMove = true;
				}		
			}

			if(!canMove)	// if the piece cannot move down then note which block is responsible
			{
				if(a == 0)
				{
					b0belowEmpty = false;
				}
				else if(a == 1)
				{
					b1belowEmpty = false;
				}
				else if(a == 2)
				{
					b2belowEmpty = false;
				}
				else if(a == 3)
				{
					b3belowEmpty = false;
				}
			}
		}
	}

	if(canMove && b0belowEmpty && b1belowEmpty  && b2belowEmpty  && b3belowEmpty)	// If the piece is ok to move down, then return true
	{
		return true;
	}
	else			// If the piece cannot move down any further then return false
	{
		return false;
	}
}

As far as I can see, it should be working perfectly, which 90% of the time it does. However, there are times when the piece will just stop moving, and a new piece is the generated, even when ti hasn't hit the bottom. I suspect that it is problem with checking whether the cell below is occupied, and then checking whether that occupied cell is actually part of the same piece or not...because when i comment out that section of the code (and therefore have no collision detection) it seems to work perfectly fine. I would appreciate any help anyone could maybe give, and thank you in advance. Hopefully someone has had the same problem lol! Thanks

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.