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

📄 rusblockview.cpp

📁 在学习MFC过程中可以试着多写点东西
💻 CPP
字号:
// RusBlockView.cpp : implementation of the CRusBlockView class
//

#include "stdafx.h"
#include "RusBlock.h"

#include "RusBlockDoc.h"
#include "RusBlockView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CRusBlockView

IMPLEMENT_DYNCREATE(CRusBlockView, CView)

BEGIN_MESSAGE_MAP(CRusBlockView, CView)
	//{{AFX_MSG_MAP(CRusBlockView)
	ON_WM_TIMER()
	ON_WM_KEYDOWN()
	ON_COMMAND(ID_GAME_START, OnGameStart)
	ON_COMMAND(ID_GAME_END, OnGameEnd)
	ON_COMMAND(ID_LEVEL_EASY, OnLevelEasy)
	ON_COMMAND(ID_LEVEL_HARD, OnLevelHard)
	ON_COMMAND(ID_LEVEL_NORMAL, OnLevelNormal)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRusBlockView construction/destruction

CRusBlockView::CRusBlockView()
{
	// TODO: add construction code here
	for(int i=0;i<HIGH;i++)
		for(int j=0;j<WIDE;j++)
			m_intState[i][j] = 0;
	m_intLevel = NORMAL;
	srand((unsigned)time(NULL));
	m_intScore = 0;
	m_CurrentCom.intComID = -1;
	m_CurrentCom.intDimension = 0;
	m_CurrentCom.pintArray = NULL;

	m_Components[0].intComID = 0;
	m_Components[0].intDimension = 2;
	m_Components[0].pintArray = new int[4];
	for(i=0;i<4;i++)
		m_Components[0].pintArray[i] = 1;

	m_Components[1].intComID = 1;
	m_Components[1].intDimension = 3;
	m_Components[1].pintArray = new int[9];
	m_Components[1].pintArray[0] = 0;
	m_Components[1].pintArray[1] = 1;
	m_Components[1].pintArray[2] = 0;
	m_Components[1].pintArray[3] = 1;
	m_Components[1].pintArray[4] = 1;
	m_Components[1].pintArray[5] = 1;
	m_Components[1].pintArray[6] = 0;
	m_Components[1].pintArray[7] = 0;
	m_Components[1].pintArray[8] = 0;

	m_Components[2].intComID = 2;
	m_Components[2].intDimension = 3;
	m_Components[2].pintArray = new int[9];
	m_Components[2].pintArray[0] = 0;
	m_Components[2].pintArray[1] = 0;
	m_Components[2].pintArray[2] = 0;
	m_Components[2].pintArray[3] = 1;
	m_Components[2].pintArray[4] = 1;
	m_Components[2].pintArray[5] = 0;
	m_Components[2].pintArray[6] = 0;
	m_Components[2].pintArray[7] = 1;
	m_Components[2].pintArray[8] = 0;

	m_Components[3].intComID = 3;
	m_Components[3].intDimension = 3;
	m_Components[3].pintArray = new int[9];
	m_Components[3].pintArray[0] = 0;
	m_Components[3].pintArray[1] = 0;
	m_Components[3].pintArray[2] = 1;
	m_Components[3].pintArray[3] = 0;
	m_Components[3].pintArray[4] = 1;
	m_Components[3].pintArray[5] = 1;
	m_Components[3].pintArray[6] = 0;
	m_Components[3].pintArray[7] = 1;
	m_Components[3].pintArray[8] = 0;

	m_Components[4].intComID = 4;
	m_Components[4].intDimension = 3;
	m_Components[4].pintArray = new int[9];
	m_Components[4].pintArray[0] = 1;
	m_Components[4].pintArray[1] = 0;
	m_Components[4].pintArray[2] = 0;
	m_Components[4].pintArray[3] = 1;
	m_Components[4].pintArray[4] = 1;
	m_Components[4].pintArray[5] = 1;
	m_Components[4].pintArray[6] = 0;
	m_Components[4].pintArray[7] = 0;
	m_Components[4].pintArray[8] = 0;

	m_Components[5].intComID = 5;
	m_Components[5].intDimension = 3;
	m_Components[5].pintArray = new int[9];
	m_Components[5].pintArray[0] = 0;
	m_Components[5].pintArray[1] = 0;
	m_Components[5].pintArray[2] = 1;
	m_Components[5].pintArray[3] = 1;
	m_Components[5].pintArray[4] = 1;
	m_Components[5].pintArray[5] = 1;
	m_Components[5].pintArray[6] = 0;
	m_Components[5].pintArray[7] = 0;
	m_Components[5].pintArray[8] = 0;

	m_Components[6].intComID = 6;
	m_Components[6].intDimension = 4;
	m_Components[6].pintArray = new int[16];
	m_Components[6].pintArray[0] = 0;
	m_Components[6].pintArray[1] = 1;
	m_Components[6].pintArray[2] = 0;
	m_Components[6].pintArray[3] = 0;
	m_Components[6].pintArray[4] = 0;
	m_Components[6].pintArray[5] = 1;
	m_Components[6].pintArray[6] = 0;
	m_Components[6].pintArray[7] = 0;
	m_Components[6].pintArray[8] = 0;
	m_Components[6].pintArray[9] = 1;
	m_Components[6].pintArray[10] = 0;
	m_Components[6].pintArray[11] = 0;
	m_Components[6].pintArray[12] = 0;
	m_Components[6].pintArray[13] = 1;
	m_Components[6].pintArray[14] = 0;
	m_Components[6].pintArray[15] = 0;



	
}

CRusBlockView::~CRusBlockView()
{
	for(int i=0;i<MAXCOM;i++)
		delete [] m_Components[i].pintArray;
	delete [] m_CurrentCom.pintArray;
}

BOOL CRusBlockView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CRusBlockView drawing

void CRusBlockView::OnDraw(CDC* pDC)
{
	CRusBlockDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	CBrush brushBK(RGB(135,197,255));
	CBrush * pbrushOld = pDC->SelectObject(&brushBK);
	pDC->Rectangle(LEFT - 1,TOP - 1,LEFT + WIDE * SIZE + 1,
		           TOP + HIGH * SIZE + 1);

	CBrush brushStick(RGB(127,127,127));
	pDC->SelectObject(&brushStick);
	for(int i=0;i<HIGH;i++)
		for(int j=0;j<WIDE;j++)
			if(m_intState[i][j] == 1)
				pDC->Rectangle(LEFT + SIZE * j,TOP + SIZE * i,LEFT + SIZE * (j + 1),
				               TOP + SIZE * (i + 1));

	if(m_CurrentCom.intComID >= 0)
	{
		CBrush brushCom(RGB(0,255,0));
		pDC->SelectObject(&brushCom);
		int intDimension = m_CurrentCom.intDimension;
		for(int i=0;i<intDimension * intDimension;i++)
		{
			if(m_CurrentCom.pintArray[i] == 1)
			{
				int m = ptIndex.x + i / intDimension;
				int n = ptIndex.y + (i % intDimension);
				pDC->Rectangle(LEFT + SIZE * n,TOP + SIZE * m,LEFT + SIZE * (n + 1),
					           TOP + SIZE * (m + 1));
			}
		}
	}
	CString strOut;
	strOut.Format("得分 %d",m_intScore);
	pDC->TextOut(LEFT + WIDE * SIZE + 50,TOP + 100,strOut);
}

/////////////////////////////////////////////////////////////////////////////
// CRusBlockView printing

BOOL CRusBlockView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CRusBlockView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CRusBlockView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CRusBlockView diagnostics

#ifdef _DEBUG
void CRusBlockView::AssertValid() const
{
	CView::AssertValid();
}

void CRusBlockView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CRusBlockDoc* CRusBlockView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CRusBlockDoc)));
	return (CRusBlockDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CRusBlockView message handlers

void CRusBlockView::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	int intDimension = m_CurrentCom.intDimension;
	if(CanDown())
	{
		MyInvalidateRect(ptIndex,intDimension);
		ptIndex.x++;
		MyInvalidateRect(ptIndex,intDimension);
	}
	else
	{
		for(int i=0;i<intDimension * intDimension;i++)
		{
			if(m_CurrentCom.pintArray[i] == 1)
			{
				int m = ptIndex.x + i / intDimension;
				int n = ptIndex.y + (i % intDimension);
				m_intState[m][n] = 1;
			}
		}
		MyInvalidateRect(ptIndex,intDimension);
		Disappear();
		if(CheckFail())
		{
			m_CurrentCom.intComID = -1;
			KillTimer(1);
			MessageBox("Game Over!");
		}
		else
			NewComponent();
	}
	
	CView::OnTimer(nIDEvent);
}

void CRusBlockView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	int intDimension = m_CurrentCom.intDimension;
	switch(nChar)
	{
	case 37:
		if(CanLeft())
		{
			MyInvalidateRect(ptIndex,intDimension);
			ptIndex.y--;
			MyInvalidateRect(ptIndex,intDimension);
		}
		break;
	case 39:
		if(CanRight())
		{
			MyInvalidateRect(ptIndex,intDimension);
			ptIndex.y++;
			MyInvalidateRect(ptIndex,intDimension);
		}
		break;
	case 38:
		if(CanRotate())
		{
			MyInvalidateRect(ptIndex,intDimension);
			int * pintNewCom = new int[intDimension * intDimension];
			for(int i=0;i<intDimension * intDimension;i++)
			{
				int intR = intDimension * (intDimension - (i % intDimension) - 1)
					       + (i / intDimension);
				pintNewCom[i] = m_CurrentCom.pintArray[intR];
			}
			for(i=0;i<intDimension * intDimension;i++)
				m_CurrentCom.pintArray[i] = pintNewCom[i];
			delete [] pintNewCom;
			MyInvalidateRect(ptIndex,intDimension);
		}
		break;
	}
	
	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CRusBlockView::NewComponent(void)
{
	int intComID = rand() % 7;
	m_CurrentCom.intComID = intComID;
	int intDimension = m_Components[intComID].intDimension;
	m_CurrentCom.intDimension = intDimension;
	delete [] m_CurrentCom.pintArray;
	m_CurrentCom.pintArray = new int[intDimension * intDimension];
	for(int i=0;i<intDimension * intDimension;i++)
		m_CurrentCom.pintArray[i] = m_Components[intComID].pintArray[i];
	ptIndex.x = 0;
	ptIndex.y = 5;

	if(CanNew())
		MyInvalidateRect(ptIndex,intDimension);
	else
	{
		m_CurrentCom.intComID = -1;
		KillTimer(1);
		MessageBox("Game Over!");
	}
}

bool CRusBlockView::CanDown(void)
{
	bool boolDown = true;
	POINT intNewIndex = ptIndex;
	intNewIndex.x++;
	int intDimension = m_CurrentCom.intDimension;
	for(int i=0;i<intDimension * intDimension;i++)
	{
		if(m_CurrentCom.pintArray[i] == 1)
		{
			int m = intNewIndex.x + i / intDimension;
			int n = intNewIndex.y + (i % intDimension);
			if(m >= HIGH || m_intState[m][n] == 1)
				boolDown = false;
		}
	}
	return boolDown;
}

bool CRusBlockView::CanLeft(void)
{
	bool boolLeft = true;
	int intDimension = m_CurrentCom.intDimension;
	POINT ptNewIndex = ptIndex;
	ptNewIndex.y--;

	for(int i=0;i<intDimension * intDimension;i++)
	{
		if(m_CurrentCom.pintArray[i] == 1)
		{
			int m = ptNewIndex.x + i / intDimension;
			int n = ptNewIndex.y + (i % intDimension);
			if(n < 0 || m_intState[m][n] == 1)
				boolLeft = false;
		}
	}
	return boolLeft;
}

bool CRusBlockView::CanRight(void)
{
	bool boolRight = true;
	int intDimension = m_CurrentCom.intDimension;
	POINT ptNewIndex = ptIndex;
	ptNewIndex.y++;
	for(int i=0;i<intDimension * intDimension;i++)
	{
		if(m_CurrentCom.pintArray[i] == 1)
		{
			int m = ptNewIndex.x + i / intDimension;
			int n = ptNewIndex.y + (i % intDimension);
			if(n >= WIDE || m_intState[m][n] == 1)
				boolRight = false;
		}
	}
	return boolRight;
}

bool CRusBlockView::CanRotate(void)
{
	bool boolRotate = true;
	int intDimension = m_CurrentCom.intDimension;
	POINT ptNewIndex = ptIndex;
	int * pintNewCom = new int[intDimension * intDimension];
	for(int i=0;i<intDimension * intDimension;i++)
	{
		int intR = intDimension * (intDimension - (i % intDimension) - 1) + (i / intDimension);
		pintNewCom[i] = m_CurrentCom.pintArray[intR];
		if(pintNewCom[i] == 1)
		{
			int m = ptNewIndex.x + i / intDimension;
			int n = ptNewIndex.y + (i % intDimension);
			if(n < 0 || m_intState[m][n] == 1 || n >= WIDE || m >= HIGH)
				boolRotate = false;
		}
	}
	delete [] pintNewCom;
	return boolRotate;
}

bool CRusBlockView::CanNew(void)
{
	bool boolNew = true;
	int intDimension = m_CurrentCom.intDimension;
	POINT ptNewIndex = ptIndex;
	for(int i=0;i<intDimension * intDimension;i++)
	{
		if(m_CurrentCom.pintArray[i] == 1)
		{
			int m = ptNewIndex.x + i / intDimension;
			int n = ptNewIndex.y + (i % intDimension);
			if(m_intState[m][n] == 1)
				boolNew = false;
		}
	}
	return boolNew;
}

bool CRusBlockView::CheckFail(void)
{
	bool boolEnd = false;
	for(int j=0;j<WIDE;j++)
		if(m_intState[0][j] == 1)
			boolEnd = true;
	return boolEnd;
}

void CRusBlockView::Disappear(void)
{
	int intLine = 0;
	for(int i = HIGH - 1;i >= 0;i--)
	{
		bool boolLine = true;
		for(int j=0;j<WIDE;j++)
			if(m_intState[i][j] == 0)
				boolLine = false;
		if(boolLine)
		{
			intLine++;
			for(int m=i;m>0;m--)
				for(int n=0;n<WIDE;n++)
					m_intState[m][n] = m_intState[m-1][n];
			for(int n=0;n<WIDE;n++)
				m_intState[0][n] = 0;
			i++;
		}
	}
	if(intLine>0)
	{
		m_intScore += (intLine - 1) * 200 + 100;
		InvalidateRect(CRect(LEFT + WIDE * SIZE + 50,
			           TOP + 100,LEFT + WIDE * SIZE + 200,TOP + 200));
	}
	InvalidateRect(CRect(LEFT,TOP,LEFT + WIDE * SIZE,TOP + HIGH * SIZE));
}



void CRusBlockView::OnGameStart() 
{
	// TODO: Add your command handler code here
	for(int i=0;i<HIGH;i++)
		for(int j=0;j<WIDE;j++)
			m_intState[i][j] = 0;
	m_intScore = 0;
	Invalidate();
	NewComponent();
	SetTimer(1,m_intLevel,NULL);
}

void CRusBlockView::OnGameEnd() 
{
	// TODO: Add your command handler code here
	KillTimer(1);
}

void CRusBlockView::OnLevelEasy() 
{
	// TODO: Add your command handler code here
	m_intLevel = EASY;
}

void CRusBlockView::OnLevelHard() 
{
	// TODO: Add your command handler code here
	m_intLevel = HARD;
}

void CRusBlockView::OnLevelNormal() 
{
	// TODO: Add your command handler code here
	m_intLevel = NORMAL;
}

void CRusBlockView::MyInvalidateRect(POINT ptStart,int intDimension)
{
	int x1 = LEFT + ptStart.y * SIZE;
	x1 = x1 > LEFT ? x1 : LEFT;
	int y1 = TOP + ptStart.x * SIZE;
	y1 = y1 > TOP ? y1 : TOP;
	int x2 = LEFT + (ptStart.y + intDimension) * SIZE;
	x2 = x2 > LEFT + WIDE * SIZE ? LEFT + WIDE * SIZE : x2;
	int y2 = TOP + (ptStart.x + intDimension) * SIZE;
	y2 = y2 > TOP + HIGH * SIZE ? TOP + HIGH * SIZE : y2;
	InvalidateRect(CRect(x1,y1,x2,y2));
}

⌨️ 快捷键说明

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