• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
ISDCaptain01

Weird glitch in my tetris game

11 posts in this topic

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));
}
0

Share this post


Link to post
Share on other sites

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.

0

Share this post


Link to post
Share on other sites

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

0

Share this post


Link to post
Share on other sites

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.

1

Share this post


Link to post
Share on other sites

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.

0

Share this post


Link to post
Share on other sites

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
0

Share this post


Link to post
Share on other sites

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

0

Share this post


Link to post
Share on other sites

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.

0

Share this post


Link to post
Share on other sites
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
0

Share this post


Link to post
Share on other sites

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
0

Share this post


Link to post
Share on other sites

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

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0