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

📄 rusblockview.cpp

📁 程序中只用了七种基本图形来实现总共的28种形状,因其采用了一种算法
💻 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_KEYDOWN()
	ON_WM_TIMER()
	ON_COMMAND(ID_GAME_START, OnGameStart)
	ON_COMMAND(ID_GAME_END, OnGameEnd)
	ON_COMMAND(ID_LEVEL_NORMAL, OnLevelNormal)
	ON_COMMAND(ID_LEVEL_HARD, OnLevelHard)
	ON_COMMAND(ID_LEVEL_EASY, OnLevelEasy)
	//}}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;

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

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

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

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

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

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

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

CRusBlockView::~CRusBlockView()
{
	for(int i=0;i<MAXCOM;i++)
		delete [] m_Componets[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::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;
	case VK_DOWN:
		if(CanDown())
		{
			MyInvalidateRect(ptIndex,intDimension);
			ptIndex.x++;
			MyInvalidateRect(ptIndex,intDimension);
		}
		break;
	}
	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

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
		{
			NewComponet();
		}
	}
	
	CView::OnTimer(nIDEvent);
}

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();
	NewComponet();
	SetTimer(1,m_intLevel,NULL);
}


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

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

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

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

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

void CRusBlockView::NewComponet(void)
{
	int intComID=rand()%7;
	m_CurrentCom.intComID=intComID;
	int intDimension=m_Componets[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_Componets[intComID].pintArray[i];

	ptIndex.x=0;
	ptIndex.y=5;

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

⌨️ 快捷键说明

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