⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shape.cpp

📁 用VC++DirectX技术的俄罗斯方块游戏
💻 CPP
字号:
// 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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -