Jump to content

  • Log In with Google      Sign In   
  • Create Account


Weird glitch in my tetris game


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
11 replies to this topic

#1 ISDCaptain01   Members   -  Reputation: 1353

Like
0Likes
Like

Posted 11 June 2014 - 06:05 PM

Im having a problem with the collision in my tetris game. When the blocks collide, the block wont stop moving until it exits the entire screen. That leads to another problem: The blocks keep falling well below the screen and than collide. What could be causing this? I have a video to demonstrate this glitch:

 

https://www.youtube.com/watch?v=_A_Pzwit_Fs

 

Also here is some source code:

 

This is my main loop where the controls are:

int main()
{
	//Initialize Allegro and all subsystems
	initAllegro();
	initColors();
	initBitMaps();

	//Screen height
	int mScreenHeight = HEIGHT-78;

	//Pieces
	Pieces mPieces;

	//Board
	Board mBoard(&mPieces, mScreenHeight);
	

	//Game
	Game mGame(&mBoard, &mPieces, mScreenHeight);

	//Set the state
	state = -1;
	ChangeState(state, title);

	//Hide the windows OS mouse cursor
	//al_hide_mouse_cursor(display);

	//Start the main timer
	al_start_timer(timer);

	//Game Loop
	while(!done)
	{
		//start the event queue
		al_wait_for_event(event_queue, &events);

		//Poll the keyboard
		al_get_keyboard_state(&keyState);

		//Check for specific key presses
		if(events.type == ALLEGRO_EVENT_KEY_DOWN)
		{
			//Quit the game
			if(events.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
				done = true;

			//Move the piece right
			if(events.keyboard.keycode == ALLEGRO_KEY_RIGHT)
			{
				if(mBoard.IsPossibleMovement(mGame.mPosX+1, mGame.mPosY,
					mGame.mPiece, mGame.mRotation) == true)
				{
					mGame.mPosX++;
				}
			}
				

			//Move the piece left
			if(events.keyboard.keycode == ALLEGRO_KEY_LEFT)
			{
				if(mBoard.IsPossibleMovement(mGame.mPosX-1, mGame.mPosY,
					mGame.mPiece, mGame.mRotation) == true)
				{
					mGame.mPosX--;
				}

			}

			//Move the piece down
			if(events.keyboard.keycode == ALLEGRO_KEY_DOWN)
			{
				if(mBoard.IsPossibleMovement(mGame.mPosX, mGame.mPosY+1,
					mGame.mPiece, mGame.mRotation) == true)
				{
					mGame.mPosY++;
				}	
			}

			//Make the piece fall down
			if(events.keyboard.keycode == ALLEGRO_KEY_X)
			{
				while(mBoard.IsPossibleMovement(mGame.mPosX, mGame.mPosY,
					                            mGame.mPiece, mGame.mRotation))
				{
					mGame.mPosY++;
				}

				//Store the piece in the board
				mBoard.StorePiece(mGame.mPosX, mGame.mPosY-1, mGame.mPiece, mGame.mRotation);

				//Check if a row of blocks has formed in the board, if so delete
				mBoard.DeletePossibleLines();

				//IF the top row is filled, than gameover
				if(mBoard.IsGameOver())
				{
					ChangeState(state, ending);
				}
				TrackStatistics(mGame.mPiece);

				//IF not, than continue the game by creating a new piece
				mGame.CreateNewPiece();

			}

			//Rotate the piece
			if(events.keyboard.keycode == ALLEGRO_KEY_Z)
			{
				if(mBoard.IsPossibleMovement(mGame.mPosX, mGame.mPosY, mGame.mPiece,
					                         (mGame.mRotation+1)%4))
				{
					mGame.mRotation = (mGame.mRotation+1)%4;
					al_play_sample_instance(rotationInstance);
				}
				
			}

			//Switch from the title screen to the playing screen
			if(events.keyboard.keycode == ALLEGRO_KEY_ENTER)
			{
				if(state == title)
					ChangeState(state, playing);
			}
			//Switch from the playing screen to the ending
			if(events.keyboard.keycode == ALLEGRO_KEY_S)
			{
				if(state == playing)
					ChangeState(state, ending);
			}
		}
		
			
		//Check if user closes the window
		if(events.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
		{
			done = true;
		}


		///////////////////////////////////////////////////////////////
		///                                                         ///
		///         Updating starts here                            ///
		///                                                         ///
		///////////////////////////////////////////////////////////////
		if(events.type == ALLEGRO_EVENT_TIMER)
		{
			if(state == title)
			{
			}
			else if(state == playing)
			{
				if(events.timer.source == dropTimer)
				{
					if(mBoard.IsPossibleMovement(mGame.mPosX, mGame.mPosY+1,
													mGame.mPiece, mGame.mRotation))
						mGame.mPosY++;
					else
					{
						mBoard.StorePiece(mGame.mPosX, mGame.mPosY, mGame.mPiece, mGame.mRotation);
						mBoard.DeletePossibleLines();
				
						if(mBoard.IsGameOver())
						{
							ChangeState(state, ending);
						}
						mGame.CreateNewPiece();
					}
				}
			}
			else if(state == ending)
			{
			}
			//draw = true;
		}

		///////////////////////////////////////////////////////////////
		///                                                         ///
		///         Rendering starts here                           ///
		///                                                         ///
		///////////////////////////////////////////////////////////////
		if(!done)
		{
			if(state == title)
			{
				al_draw_bitmap(titleScreen, 0, 0, NULL);
			}
			else if(state == playing)
			{
				al_draw_bitmap(guiScreen, 0, 0, NULL);
				DrawStatistics();

				//Draw the statistics screen pieces
				mGame.DrawPiece(-15, -9, 0, 0);
				mGame.DrawPiece(-15, -6, 1, 0);
				mGame.DrawPiece(-15, -4, 2, 1);
				mGame.DrawPiece(-15, -1, 3, 3);
				mGame.DrawPiece(-15, 2, 4, 1);
				mGame.DrawPiece(-15, 5, 5, 1);
				mGame.DrawPiece(-15, 8, 6, 1);
				mGame.DrawScene();
			}
			else if(state == ending)
			{
				al_draw_bitmap(endingScreen, 0, 0, NULL);
			}

			al_flip_display();
			al_clear_to_color(al_map_rgb(0,0,0));
			//draw = false;
		}
	}

	return 0;
}

And this is my collision code and pixel location code:

/Check if the piece can be stored at this position without any collision
//Returns true if the movement is  possible, false if its not possible
bool Board::IsPossibleMovement (int pX, int pY, int pPiece, int pRotation)
{
	// Checks collision with pieces already stored in the board or the board limits
	// This is just to check the 5x5 blocks of a piece with the appropiate area in the board
	for (int i1 = pX, i2 = 0; i1 < pX + PIECE_BLOCKS; i1++, i2++)
	{
		for (int j1 = pY, j2 = 0; j1 < pY + PIECE_BLOCKS; j1++, j2++)
		{	
			// Check if the piece is outside the limits of the board
			if (i1 < 0 			|| i1 > BOARD_WIDTH  - 1	||
				j1 > BOARD_HEIGHT - 1)
			{
				//If an actual block if the piece is outside the board,
				//than movement is not possible
				if (mPieces->GetBlockType (pPiece, pRotation, j2, i2) != 0)
					return false;		
			}

			// Check if the piece have collisioned with a block already stored in the map
			if (j1 >= 0)	
			{
				if ((mPieces->GetBlockType (pPiece, pRotation, j2, i2) != 0) &&
					(!IsFreeBlock (i1, j1))	)
					return false;
			}
		}
	}

	// No collision
	return true;
}
//Store a piece in the board by filling the block
void Board::StorePiece (int pX, int pY, int pPiece, int pRotation)
{
	// Store each block of the piece into the board
	for (int i1 = pX, i2 = 0; i1 < pX + PIECE_BLOCKS; i1++, i2++)
	{
		for (int j1 = pY, j2 = 0; j1 < pY + PIECE_BLOCKS; j1++, j2++)
		{	
			// Store only the blocks of the piece that are not empty
			if (mPieces->GetBlockType (pPiece, pRotation, j2, i2) != 0)	
			{
				mBoard[i1][j1] = POS_FILLED;
				al_play_sample_instance(collideInstance);
			}

		}
	}
}
//Returns the horizontal position (in pixels) of the block given like parameter
int Board::GetXPosInPixels(int pPos)
{
	return( (BOARD_POSITION - (BLOCK_SIZE * (BOARD_WIDTH / 2))) + (pPos * BLOCK_SIZE));
}

//Returns the vertical position (in pixels) of the block given like parameter
int Board::GetYPosInPixels(int pPos)
{
	return( (mScreenHeight - (BLOCK_SIZE *(BOARD_HEIGHT / 2))) + (pPos * BLOCK_SIZE));
}


Sponsor:

#2 NewVoxel   Members   -  Reputation: 303

Like
0Likes
Like

Posted 11 June 2014 - 06:57 PM

I've scanned through it a dozen times, but can't seem to find much. It's probably nothing but I did notice an inconsistency with with your GetBlockType

if (mPieces->GetBlockType (pPiece, pRotation, j2, i2) != 0)

that you seem to be passing in your Y value j2 before your X value i2. Is it meant to be like this or have you accidentally switched the order in which you pass them into the function? Just strange that everything else addresses the x values first.


Your authority is not recognized in Fort Kick-ass http://www.newvoxel.com


#3 ISDCaptain01   Members   -  Reputation: 1353

Like
0Likes
Like

Posted 12 June 2014 - 12:50 AM

I've scanned through it a dozen times, but can't seem to find much. It's probably nothing but I did notice an inconsistency with with your GetBlockType

if (mPieces->GetBlockType (pPiece, pRotation, j2, i2) != 0)

that you seem to be passing in your Y value j2 before your X value i2. Is it meant to be like this or have you accidentally switched the order in which you pass them into the function? Just strange that everything else addresses the x values first.

 

Its accessing a 4x4 array (yuck I know). I cant find the bug either. Im gonna look more tommorow



#4 dejaime   Crossbones+   -  Reputation: 3968

Like
1Likes
Like

Posted 12 June 2014 - 09:29 AM

Can you still move the piece around while it glitches?

 

Have you tried using a debugger? I'd debug the IsPossibleMovement and GetBlockType functions first. I can't do that since it appears to be missing code.



#5 DiegoSLTS   Members   -  Reputation: 977

Like
0Likes
Like

Posted 12 June 2014 - 10:22 AM

Check what values are passed as pY in IsPossibleMovement for a single piece since it appears on the top and it collides at the bottom, it should be incremental by 1 position up to a number between BOARD_HEIGHT - 1 and BOARD_HEIGHT - 5 I guess.

 

Also, where do you reset mGame.mPosX and mPosY for new pieces? What's that reset value?

 

And related to that... is the piece supposed to appear fully visible or above the board? Maybe you're drawing the pieces some "blocks" lower than you should.



#6 StaticPoof   Members   -  Reputation: 245

Like
0Likes
Like

Posted 13 June 2014 - 09:39 AM

I can't really tell from your code, but it looks like your program does properly check for collisions and stores where those collisions are.  My intuition tells me that your program doesn't break after a collision is detected and skip to the next piece.  

 

If you have any logic that is supposed to do that in your code I'd put a breakpoint there and see if it is ever reached.  If not it should be pretty straightforward to implement happy.png  


Edited by StaticPoof, 13 June 2014 - 09:40 AM.


#7 ISDCaptain01   Members   -  Reputation: 1353

Like
0Likes
Like

Posted 13 June 2014 - 12:05 PM

http://javilop.com/gamedev/tetris-tutorial-in-c-platform-independent-focused-in-game-logic-for-beginners/

 

That's the tutorial im following. I try resetting everything back to default position and still occurs. Im still looking

 

I checked out his .exe and he doesn't seem to have this problem


Edited by ISDCaptain01, 13 June 2014 - 12:06 PM.


#8 BHXSpecter   Members   -  Reputation: 1242

Like
0Likes
Like

Posted 13 June 2014 - 01:18 PM

Have you compared your code to his downloadable code? Could be that you are forgetting something that he hadn't covered. 


"Through vengence I was born.Through war I was trained.Through love I was found. Through death I was released. Through release I was given a purpose."


#9 DiegoSLTS   Members   -  Reputation: 977

Like
0Likes
Like

Posted 13 June 2014 - 01:22 PM

Are you using a debug tool? Everything we told you to check have correct values?

 

Try reducing the board to something like 10 blocks tall and draw it as close as you can from the top of the screen (or add more height to the window), I still think that you're drawing the pieces in the wrong place and the collision is happening when the piece is too far down.



#10 ISDCaptain01   Members   -  Reputation: 1353

Like
0Likes
Like

Posted 13 June 2014 - 05:06 PM

DiegoSLTS, on 13 Jun 2014 - 12:22 PM, said:

Are you using a debug tool? Everything we told you to check have correct values?

 

Try reducing the board to something like 10 blocks tall and draw it as close as you can from the top of the screen (or add more height to the window), I still think that you're drawing the pieces in the wrong place and the collision is happening when the piece is too far down.

 

You are correct, I counted how many cells the block falls and it is exactly what the macro defines but for some reason it is not synced with the board. I just don't know hwta s causing it


Edited by ISDCaptain01, 13 June 2014 - 05:13 PM.


#11 Vortez   Crossbones+   -  Reputation: 2688

Like
0Likes
Like

Posted 13 June 2014 - 05:57 PM

You can have a look at mine on github if you wish. just look for the .cs files.

 

You should also take a look at this btw.


Edited by Vortez, 13 June 2014 - 05:59 PM.


#12 ISDCaptain01   Members   -  Reputation: 1353

Like
0Likes
Like

Posted 15 June 2014 - 12:18 AM

Lol im such an idiot. I was trying to modify a const when passing in my screenheight and it wasn't working. Just used an actual number and it works. smh lol






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS