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

📄 blockview.cpp

📁 俄罗斯方块游戏 MFC 源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// blockView.cpp : implementation of the CBlockView class
//

#include "stdafx.h"
#include "block.h"

#include "blockDoc.h"
#include "blockView.h"
#include "MainFrm.h"
#include <mmsystem.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//--------------------------------------------------------
#define START_X		5
#define TIMER_ID	1
#define API_TIMER	2
#define MAX_LINE	20
const UINT uInverval[9]=
{
	500,400,350,300,250,200,150,100,50
};
UINT uAPI_Timer;
void CALLBACK TimeProc(UINT uID,UINT uMsg,DWORD dwUser,DWORD dw1,DWORD dw2);

//--------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
// CBlockView
IMPLEMENT_DYNCREATE(CBlockView, CView)

BEGIN_MESSAGE_MAP(CBlockView, CView)
	//{{AFX_MSG_MAP(CBlockView)
	ON_COMMAND(ID_START, OnStart)
	ON_COMMAND(ID_STOP, OnStop)
	ON_UPDATE_COMMAND_UI(ID_START, OnUpdateStart)
	ON_UPDATE_COMMAND_UI(ID_STOP, OnUpdateStop)
	ON_WM_ERASEBKGND()
	ON_WM_TIMER()
	ON_WM_KEYDOWN()
	ON_COMMAND(ID_BKCOLOR, OnBkcolor)
	ON_COMMAND(ID_BLOCKCOLOR, OnBlockcolor)
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBlockView construction/destruction

CBlockView::CBlockView()
{
	// TODO: add construction code here

}

CBlockView::~CBlockView()
{
}

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

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CBlockView drawing

void CBlockView::OnDraw(CDC* pDC)
{
	CBlockDoc* pDoc = GetDocument();
	int i,j;
	CRect rect;
	CBrush brush;
	brush.CreateSolidBrush(pDoc->m_clrBlock);
	ASSERT_VALID(pDoc);
	for(i=0;i<20;i++)
		for(j=0;j<12;j++)
		{
			rect.SetRect(j*20,i*20,j*20+20,i*20+20);
			if(pDoc->m_iMap[i][j]==1)
			{
				pDC->FillRect(&rect,&brush);
				pDC->DrawEdge(&rect,EDGE_RAISED,BF_RECT);
			}
		}
	ShowSquare();
	if(!m_bAPITimerRunning)
	{
		::timeBeginPeriod(1);
		uAPI_Timer=::timeSetEvent(1000,0,TimeProc,(DWORD)(this->m_hWnd),TIME_PERIODIC);
		m_bAPITimerRunning=TRUE;

	}
}

/////////////////////////////////////////////////////////////////////////////
// CBlockView diagnostics

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

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

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

/////////////////////////////////////////////////////////////////////////////
// CBlockView message handlers
//--------------------------------------------------------
void CBlockView::OnStart() 
{
	// TODO: Add your command handler code here
	CBlockDoc *pDoc=GetDocument();
	m_bRunning=TRUE;
	ShowPreView();
	SetTimer(TIMER_ID,uInverval[pDoc->m_iLevel],NULL);
}
void CBlockView::OnStop() 
{
	// TODO: Add your command handler code here
	if(m_bRunning)
	{
		m_bRunning=FALSE;
		KillTimer(TIMER_ID);
	}
}
void CBlockView::OnInitialUpdate() 
{
	CView::OnInitialUpdate();
	CBlockDoc *pDoc=GetDocument();
	m_bAPITimerRunning=FALSE;
	((CMainFrame *)AfxGetMainWnd())->ChangeLevelSel(pDoc->m_iLevel);
	if(m_bRunning)
	{
		m_bRunning=FALSE;
		KillTimer(TIMER_ID);
	}
}
//--------------------------------------------------------
void CBlockView::OnUpdateStart(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(!m_bRunning);
}

void CBlockView::OnUpdateStop(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(m_bRunning);
}
//--------------------------------------------------------
BOOL CBlockView::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default
	CRect rect;
	int width,height;
	CBlockDoc *pDoc=GetDocument();
	GetClientRect(&rect);
	width=rect.Width();
	height=rect.Height();
	rect.right=240;
	CBrush brush(pDoc->m_clrBack);
	pDC->FillRect(&rect,&brush);
	rect.left=rect.right;
	rect.right=width;
	brush.DeleteObject();
	brush.CreateSolidBrush(pDoc->m_clrBlock);
	pDC->FillRect(&rect,&brush);
	pDC->DrawEdge(&rect,EDGE_BUMP,BF_RECT);

	rect.bottom=rect.top+30;
	pDC->SetBkColor(pDoc->m_clrBlock);
	pDC->SetTextColor(~pDoc->m_clrBlock);
	pDC->DrawText(_T("下一个方块:"),&rect,DT_SINGLELINE|DT_VCENTER|DT_CENTER);

	rect.top=rect.top+30;
	rect.bottom=rect.Width();
	rect.InflateRect(-2,-2);
	pDC->DrawEdge(&rect,EDGE_SUNKEN,BF_RECT);

	rect.top=rect.bottom;
	rect.bottom+=30;
	pDC->DrawText(_T("自述:"),&rect,DT_SINGLELINE|DT_VCENTER|DT_CENTER);
	rect.top=rect.bottom;
	rect.bottom=height-2;
	pDC->DrawEdge(&rect,EDGE_SUNKEN,BF_RECT);
	ShowPreView();
	return TRUE;
}
void CBlockView::ShowSquare()
{
	CBlockDoc *pDoc=GetDocument();
	CRect	rect;
	CClientDC dc(this);
	CBrush brush;
	brush.CreateSolidBrush(pDoc->m_clrBlock);
	for(int i=0;i<4;i++)
	{
		rect.SetRect(pDoc->m_ptCurrentPos[i].x*20,
					 pDoc->m_ptCurrentPos[i].y*20,
					 pDoc->m_ptCurrentPos[i].x*20+20,
					 pDoc->m_ptCurrentPos[i].y*20+20);
		dc.FillRect(&rect,&brush);
		dc.DrawEdge(&rect,EDGE_RAISED,BF_RECT);
	}
}
void CBlockView::HideSquare()
{
	CBlockDoc *pDoc=GetDocument();
	CRect	rect;
	CClientDC dc(this);
	CBrush brush;
	brush.CreateSolidBrush(pDoc->m_clrBack);
	for(int i=0;i<4;i++)
	{
		rect.SetRect(pDoc->m_ptCurrentPos[i].x*20,
					 pDoc->m_ptCurrentPos[i].y*20,
					 pDoc->m_ptCurrentPos[i].x*20+20,
					 pDoc->m_ptCurrentPos[i].y*20+20);
		dc.FillRect(&rect,&brush);
	}
}
void CBlockView::DeleteLine(int iIndex) //iIndex is 0 based
{
	int i;
	CRect rect;
	CBlockDoc *pDoc=GetDocument();
	for(i=iIndex;i>=1;i--)
		memcpy(pDoc->m_iMap[i],pDoc->m_iMap[i-1],12*sizeof(int));
	memset(pDoc->m_iMap,0,12*sizeof(int));
	rect.SetRect(0,0,12*20,(iIndex+1)*20);
	ScrollWindow(0,20,&rect,&rect);
}
//--------------------------------------------------------
void CBlockView::CreateSquare()
{
	int i;
	CBlockDoc *pDoc=GetDocument();
	pDoc->m_iShape=pDoc->m_iNextShape;
	pDoc->m_iNextShape=rand()%7;
	pDoc->m_iState=0;
	switch(pDoc->m_iShape)
	{
	case 0:						// @@@@
		for(i=0;i<4;i++)
		{
			pDoc->m_ptCurrentPos[i].x=START_X+i;
			pDoc->m_ptCurrentPos[i].y=0;
		}
		break;			
	case 1:						// @
								// @@@
		pDoc->m_ptCurrentPos[0].x=START_X;
		pDoc->m_ptCurrentPos[0].y=0;
		for(i=1;i<4;i++)
		{
			pDoc->m_ptCurrentPos[i].x=START_X+i-1;
			pDoc->m_ptCurrentPos[i].y=1;
		}
		break;
	case 2:						//   @
								// @@@
		pDoc->m_ptCurrentPos[0].x=START_X+2;
		pDoc->m_ptCurrentPos[0].y=0;
		for(i=1;i<4;i++)
		{
			pDoc->m_ptCurrentPos[i].x=START_X+i-1;
			pDoc->m_ptCurrentPos[i].y=1;
		}
		break;
	case 3:						// @@
								//	@@
		for(i=0;i<2;i++)
		{
			pDoc->m_ptCurrentPos[i].x=START_X+i;
			pDoc->m_ptCurrentPos[i].y=0;
		}
		for(i=2;i<4;i++)
		{
			pDoc->m_ptCurrentPos[i].x=START_X+i-1;
			pDoc->m_ptCurrentPos[i].y=1;
		}
		break;
	case 4:						//  @@
								// @@
		for(i=0;i<2;i++)
		{
			pDoc->m_ptCurrentPos[i].x=START_X+i+1;
			pDoc->m_ptCurrentPos[i].y=0;
		}
		for(i=2;i<4;i++)
		{
			pDoc->m_ptCurrentPos[i].x=START_X+i-2;
			pDoc->m_ptCurrentPos[i].y=1;
		}
		break;
	case 5:						//  @
								// @@@
		pDoc->m_ptCurrentPos[0].x=START_X+1;
		pDoc->m_ptCurrentPos[0].y=0;
		for(i=1;i<4;i++)
		{
			pDoc->m_ptCurrentPos[i].x=START_X+i-1;
			pDoc->m_ptCurrentPos[i].y=1;
		}
		break;
	default :					// @@
								// @@
		for(i=0;i<4;i++)
		{
			pDoc->m_ptCurrentPos[i].x=START_X+i%2;
			pDoc->m_ptCurrentPos[i].y=(i<=1)?0:1;
		}
		break;
	}
}
//---------------------------------------------------------------
void CBlockView::OnTimer(UINT nIDEvent) 
{
	int i,j;
	BOOL bAbleToDrop;
	UINT uDeleteLineInfo=0;
	UINT iLineNumInfo=0;
	CBlockDoc *pDoc=GetDocument();
	bAbleToDrop=TRUE;
	for(i=0;i<4;i++)                 //verify if end game
	{
		if(pDoc->m_iMap[pDoc->m_ptCurrentPos[i].y][pDoc->m_ptCurrentPos[i].x]==1)
		{
			KillTimer(TIMER_ID);
			MessageBox(_T("你已经失败!\n请重新建游戏并开始!"),_T("Warning!"),MB_ICONWARNING|MB_OK);
			m_bRunning=FALSE;
			return;
		}
	}
	for(i=0;i<4;i++)                 //verify if able to drop
	{
		if((pDoc->m_iMap[pDoc->m_ptCurrentPos[i].y+1][pDoc->m_ptCurrentPos[i].x]==1)
			||pDoc->m_ptCurrentPos[i].y==19)
		{
			bAbleToDrop=FALSE;
			break;
		}
	}
	if(bAbleToDrop)
	{
		HideSquare();
		for(i=0;i<4;i++)  
			pDoc->m_ptCurrentPos[i].y++;        //drop one line
		ShowSquare();
	}
	else										// not able to drop
	{
		for(i=0;i<4;i++)  
			pDoc->m_iMap[pDoc->m_ptCurrentPos[i].y][pDoc->m_ptCurrentPos[i].x]=1;
		for(i=0;i<20;i++)
		{
			for(j=0;j<12;j++)
			{
				if(pDoc->m_iMap[i][j]==0)
					break;
			}
			if(j==12)             // has one line to delete
				uDeleteLineInfo=uDeleteLineInfo|(1L<<i);
		}
		for(i=0;i<20;i++)
			if( ( (uDeleteLineInfo>>i) & 1L)!=0)
				iLineNumInfo++;
		if(uDeleteLineInfo!=0)    //need to delete line
		{
			for(i=0;i<20;i++)
			{
				if( ( (uDeleteLineInfo>>i) & 1L)!=0)
					DeleteLine(i);
			}
			if(iLineNumInfo==1)
				pDoc->m_uScore+=100;
			else if(iLineNumInfo==2)
				pDoc->m_uScore+=300;
			else if(iLineNumInfo==3)
				pDoc->m_uScore+=500;
			else
				pDoc->m_uScore+=1000;
			if(pDoc->m_uScore%2000==0)
			{
				pDoc->m_iLevel=min(pDoc->m_iLevel+1,8);
				((CMainFrame *)AfxGetMainWnd())->ChangeLevelSel(pDoc->m_iLevel);
			}
		}
		CreateSquare();
		ShowSquare();
		ShowPreView();
	}
	CView::OnTimer(nIDEvent);
}

//-----------------------------------------------------------------
void CBlockView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	switch(nChar)
	{
	case VK_LEFT:
		GoLeft();
		break;
	case VK_RIGHT:
		GoRight();
		break;
	case VK_DOWN:
		GoFastDown();
		break;
	case VK_UP:
		ChangeState();
		break;
	}
	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
//--------------------------------------------------------
void CBlockView::GoLeft()
{
	int i;
	CBlockDoc *pDoc=GetDocument();
	for(i=0;i<4;i++)
	{
		if(pDoc->m_ptCurrentPos[i].x<=0)
			return;
		if(pDoc->m_iMap[pDoc->m_ptCurrentPos[i].y][pDoc->m_ptCurrentPos[i].x-1]==1)
			return;
	}
	HideSquare();
	for(i=0;i<4;i++)
		pDoc->m_ptCurrentPos[i].x-=1;
	ShowSquare();
}

void CBlockView::GoRight()
{
	int i;
	CBlockDoc *pDoc=GetDocument();
	for(i=0;i<4;i++)
	{
		if(pDoc->m_ptCurrentPos[i].x>=11)
			return ;
		else if(pDoc->m_iMap[pDoc->m_ptCurrentPos[i].y][pDoc->m_ptCurrentPos[i].x+1]==1)
			return;
	}
	HideSquare();
	for(i=0;i<4;i++)
		pDoc->m_ptCurrentPos[i].x+=1;
	ShowSquare();
}
void CBlockView::GoFastDown()
{
	int i;
	CBlockDoc *pDoc=GetDocument();
	if(!m_bRunning)
		return;
	for(i=0;i<4;i++)
	{
		if(pDoc->m_ptCurrentPos[i].y>=19)
			return ;
		else if(pDoc->m_iMap[pDoc->m_ptCurrentPos[i].y+1][pDoc->m_ptCurrentPos[i].x]==1)
			return;
	}
	HideSquare();
	for(i=0;i<4;i++)
		pDoc->m_ptCurrentPos[i].y+=1;
	ShowSquare();
}
//--------------------------------------------------------
void CBlockView::ChangeState()
{
	int i;
	CBlockDoc *pDoc=GetDocument();
	switch(pDoc->m_iShape)
	{
	case 0:
		if(pDoc->m_iState==0)		
		{
			if(pDoc->m_ptCurrentPos[0].y<=0||pDoc->m_ptCurrentPos[0].y>=18)
				return;
			if((pDoc->m_iMap[pDoc->m_ptCurrentPos[1].y+1][pDoc->m_ptCurrentPos[1].x]==1)
				||(pDoc->m_iMap[pDoc->m_ptCurrentPos[1].y+2][pDoc->m_ptCurrentPos[1].x]==1))
				return;
			HideSquare();
			for(i=0;i<4;i++)
			{
				pDoc->m_ptCurrentPos[i].y=pDoc->m_ptCurrentPos[1].y+i-1;

⌨️ 快捷键说明

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