Click here to Skip to main content
Click here to Skip to main content
Articles » Multimedia » DirectX » Games » Downloads
 
Add your own
alternative version

Falling Blocks

, 17 Apr 2008 CPOL
A game written using Visual C++ and DirectX.
fallingblocks.zip
FallingBlocks.exe
fallingblocksvc7.zip
FallingBlocks
Block are Falling.doc
DirectX.ico
Drowning.wav
Graphics.bmp
LineComplete.wav
Move.wav
Place.wav
Web Falling Blocks.doc
fallingblocksvs2008.zip
Block are Falling.doc
DirectX.ico
Drowning.wav
FallingBlocks.suo
Graphics.bmp
LineComplete.wav
Move.wav
Place.wav
Web Falling Blocks.doc
fallingblocks_src.zip
Block are Falling.doc
DirectX.ico
Drowning.wav
FallingBlocks.dsp
FallingBlocks.dsw
Graphics.bmp
LineComplete.wav
Move.wav
Place.wav
Web Falling Blocks.doc
// Shape.cpp: implementation of the CShape class.
//
//////////////////////////////////////////////////////////////////////

#include <windows.h>
#include "BlockList.h"
#include "FlooredBlocks.h"
#include "Shape.h"
#include "resource.h"

extern HINSTANCE g_hInstance;

const short CShape::m_pStockShapes[] = { 
	    11,   // No Of shapes in the array
		2 /*No of orientation shapes */, 4 /*No Of blocks for this shape*/, 
		2,1, 2,2, 3,2, 3,3,     //  O
		1,2, 2,2, 2,1, 3,1,     //  OO 
		                        //   O 
		0,   // Each shape ends with a 0, Takes out the maths challenge :)

		2,4, 
		1,2, 2,2, 3,2, 4,2,     // OOOO
		2,1, 2,2, 2,3, 2,4,
		0,
		2,4, 
		2,1, 2,2, 1,2, 1,3,     //   O
		1,1, 2,1, 2,2, 3,2,     //  OO
		0,                      //  O 

		1,4, 
		2,1, 3,1, 3,2, 2,2,     //  OO
		0,                      //  OO  

		4,4, 
		2,2, 3,2, 2,3, 2,4,     //  OO 
		2,2, 2,3, 3,3, 4,3,     //  O
		3,1, 3,2, 2,3, 3,3,     //  O
		1,2, 2,2, 3,2, 3,3,
		0,

		4,4, 
		2,1, 2,2, 2,3, 3,3,     //  O
		1,3, 2,3, 3,3, 3,2,     //  O
		2,2, 3,2, 3,3, 3,4,     //  OO
		2,2, 3,2, 4,2, 2,3,     
		0,

		4,4, 
		2,1, 1,2, 2,2, 3,2,     //   O
		2,1, 1,2, 2,2, 2,3,     //  OOO 
		1,2, 2,2, 3,2, 2,3,     //   
		2,1, 2,2, 3,2, 2,3,
		0,
///////////////////////   Crazy //////////////////////
		1,4,
		2,1,1,2,3,2,2,3,        //   O
		0,                      //  O O
		                        //   O

    	1,8,                                  //  OOO
		1,1,2,1,3,1, 1,2,3,2, 1,3,2,3,3,3,    //  O O
		0,						              //  OOO

    	4,5,                                  //  OOO
		1,1,2,1,3,1, 1,2,3,2,                 //  O O
		1,1,2,1, 1,2, 1,3,2,3,
		1,2,1,3,2,3,3,3, 3,2,
		2,1,3,1,3,2,2,3,3,3,
		0,

		1,5, 
		2,1, 1,2, 2,2, 3,2, 2,3,    //   O
		                            //  OOO 
		                            //   O
		0,

};

short CShape::s_nNoOfShapes =0;
short CShape::s_cShapesArrayUsage=0;
short CShape::s_nMaxNoOfShapesAllowed=0;
const short** CShape::s_pShapes = NULL;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CShape::CShape(CFlooredBlocks* pFlooredBlocks, const short* pShapes):m_nX(0), m_nY(0)
{
	m_pFlooredBlocks = pFlooredBlocks;
	
	if (s_cShapesArrayUsage == 0) {
		s_nNoOfShapes = *pShapes;
		if (s_nMaxNoOfShapesAllowed == 0)
			s_nMaxNoOfShapesAllowed = s_nNoOfShapes;
		s_pShapes = new const short*[	s_nNoOfShapes];
		if (s_pShapes == NULL) {
			OutputDebugString("Failed to allocate memory to help the pointer to shape array\n");
			return;
		}
		const short* pCurrShape = pShapes + 1; // +1 to go past the No of shapes 
		
		for (short nI =0; nI < 	s_nNoOfShapes ; nI++)
		{
			s_pShapes[nI]= pCurrShape;
			while (*pCurrShape++); // Go to the next shape.
		}
	}
	s_cShapesArrayUsage++; // Increment the array usage
	
	/* if s_nMaxNoOfShapesAllowed is out of range set it to Total No of shapes */
	if (s_nMaxNoOfShapesAllowed < 0 && s_nMaxNoOfShapesAllowed > s_nNoOfShapes) {
		s_nMaxNoOfShapesAllowed = s_nNoOfShapes;
	}

}

CShape::~CShape()
{
	s_cShapesArrayUsage--; // Decrement the array usage
	if (s_cShapesArrayUsage == 0 ) { // If no one is using it delete the array
		delete[] s_pShapes;
		s_pShapes = NULL;
	}
}

bool CShape::CreateRandShape(short nX, short nY)
{
	m_nColor = rand() % NUM_COLORS;
	m_nShape = rand() % s_nMaxNoOfShapesAllowed;
	m_nRotate = 0;
	m_nX = nX;
	m_nY = nY;
	return CreateShape();
}
//////////////////////////////////////////////////////////
// Creates a shape using the Shape array information
// Creates a list of blocks and gives them the coordinates
// from the array.
//////////////////////////////////////////////////////////
bool CShape::CreateShape()
{
	const short* pShape = s_pShapes[m_nShape];
	SBlock Block;
	m_nTotalRotate = *pShape++;  
	short nNoOfBlocks   = *pShape++;
	pShape+= m_nRotate * nNoOfBlocks * 2;

	const short* pShapeSave = pShape;  // Save the pointer

    // Check for Boundary and Collusion.
	for (int nI = 0 ; nI < nNoOfBlocks ; nI++) {
		Block.nX = *pShape + m_nX;
		pShape++;
		Block.nY = *pShape + m_nY;
		pShape++;
		if (Block.nX  < m_pFlooredBlocks->m_rcBoundary.left || 
			Block.nX  > m_pFlooredBlocks->m_rcBoundary.right)
			return false;
		
		if (Block.nY  > m_pFlooredBlocks->m_rcBoundary.bottom || 
			Block.nY  < m_pFlooredBlocks->m_rcBoundary.top)
			return false;

		if (m_pFlooredBlocks->IsOccupied(Block.nX,Block.nY))
			return false;
	}

	pShape = pShapeSave;  // Use the saved pointer
	Destroy();
	for (nI = 0 ; nI < nNoOfBlocks ; nI++) {
		Block.nColor = m_nColor;
		Block.nX = *pShape;
		pShape++;
		Block.nY = *pShape;
		pShape++;
		Add(Block);
	}
	return true;
}

void CShape::Display()
{
	CBlockList::Display(m_nX, m_nY);
}

bool CShape::MoveTo(short nX, short nY)
{
	m_nX = nX;
	m_nY = nY;
	return true;
}

//////////////////////////////////
// Dumps the List to debugger
///////////////////////////////////
void CShape::dbgDisplay()
{
	CBlockList::dbgDisplay();

}

bool CShape::MoveLeft()
{
	if (IsContained(m_pFlooredBlocks->m_rcBoundary, m_nX-1, m_nY)) {
		if (m_pFlooredBlocks->IsOccupied(*this, m_nX-1, m_nY) == false) {
			m_nX--;
			return true;
		}
	}
	return false;
}

bool CShape::MoveRight()
{
	if (IsContained(m_pFlooredBlocks->m_rcBoundary, m_nX+1, m_nY)) {
		if (m_pFlooredBlocks->IsOccupied(*this, m_nX+1, m_nY) == false) {
			m_nX++;
			return true;
		}
	}
	return false;

}

bool CShape::MoveDown()
{
	if (IsContained(m_pFlooredBlocks->m_rcBoundary, m_nX, m_nY+1)) {
		if (m_pFlooredBlocks->IsOccupied(*this, m_nX, m_nY+1) == false) {
			m_nY++;
			return true;
		}
	}
 
	return false;
}

bool CShape::MoveUp()
{
	if (IsContained(m_pFlooredBlocks->m_rcBoundary, m_nX, m_nY-1)) {
		m_nY--;
		return true;
	}
	return false;
}


bool CShape::Rotate()
{
	short nRotate = m_nRotate;
	m_nRotate++;
	if (m_nRotate == m_nTotalRotate)
		m_nRotate = 0;
		
	if (CreateShape() == false)
		m_nRotate = nRotate;
	return true;
}

void CShape::NextShape()
{
	m_nShape += 1;
	if (m_nShape == s_nMaxNoOfShapesAllowed)
		m_nShape = 0;

	m_nRotate =0;
	Destroy();
	CreateShape();

}

////////////////////////////////////////////////////
//  Check if the Block offset by X ,Y is within
//  given boundary
////////////////////////////////////////////////////
bool CShape::IsContained(RECT rcBoundary, short nX, short nY)
{
	SNODE* pCurr = m_pListHead->pNext;
	while (pCurr) {
		SBlock Block= pCurr->Block;
		if ((Block.nX + nX) < rcBoundary.left || (Block.nX + nX) > rcBoundary.right)
			return false;
		
		if ((Block.nY + nY) > rcBoundary.bottom || (Block.nY + nY) < rcBoundary.top)
			return false;
		pCurr=pCurr->pNext;
	}
	return true;
}

/////////////////////////////////////////////
// Convert to actual coordinates in space
/////////////////////////////////////////////
void CShape::ConvertToSpaceCoord()
{
	SNODE* pCurr = m_pListHead->pNext;
	while (pCurr) {
		pCurr->Block.nX =pCurr->Block.nX  + m_nX;
		pCurr->Block.nY =pCurr->Block.nY + m_nY;
		pCurr= pCurr->pNext;
	}
}

//////////////////////////////////////////////////////////////////
// This number can be set to limit the shapes that will be 
// used from the array. 
// This way some crazy shapes can be added to the end of the 
// array and only be used if the user switches to the crazy mode.
/////////////////////////////////////////////////////////////////
bool CShape::SetMaxNoOfShapesAllowed(short nMax /*= s_nNoOfShapes*/)
{
	if (s_cShapesArrayUsage ==0)  {// No objects are created so s_nNoShapes may be 0
		                          // because the constructor may not have been called yet
								  // Testing on s_nMaxNoOfShapesAllowed is done in the constructor
		s_nMaxNoOfShapesAllowed = nMax;
	}
	if (nMax > 0 && nMax <= s_nNoOfShapes) {
		s_nMaxNoOfShapesAllowed = nMax;
		return true;
	}
	return false;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Xavier John
Software Developer
United States United States
No Biography provided

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141216.1 | Last Updated 17 Apr 2008
Article Copyright 2001 by Xavier John
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid