www.gusucode.com > 界面很独特的VC++俄罗斯方块源代码-源码程序 > 界面很独特的VC++俄罗斯方块源代码-源码程序\code\CGamePlatform.cpp

    // CGamePlatform.cpp : implementation of the CGamePlatform class
// Download by http://www.NewXing.com

#include "stdafx.h"
#include "Diamond.h"

#include "CGamePlatform.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define CUBEWIDTH 20
#define BOUNDARY_WIDTH  6
#define BOUNDARY_HEIGHT 60
/////////////////////////////////////////////////////////////////////////////
// CGamePlatform

IMPLEMENT_DYNAMIC(CGamePlatform, CFrameWnd)

BEGIN_MESSAGE_MAP(CGamePlatform, CFrameWnd)
	//{{AFX_MSG_MAP(CGamePlatform)
	ON_WM_ERASEBKGND()
	ON_WM_TIMER()
	ON_WM_KEYDOWN()
    ON_WM_PAINT()
	ON_WM_KEYUP()
	ON_WM_CREATE()
	ON_WM_NCHITTEST()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_GAMECONTROL, OnGameCtrlClick)
    ON_BN_CLICKED(IDC_GAMEMINIMIZE, CFrameWnd::CloseWindow)
    ON_BN_CLICKED(IDC_GAMEEXIT, CFrameWnd::OnClose)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGamePlatform construction/destruction

CGamePlatform::CGamePlatform()
{
	Create(NULL,_T("Diamond"),WS_OVERLAPPEDWINDOW,CRect(400,80,855,679));
	m_bitmapBgnd.LoadBitmap(IDB_BACKGROUND);
	m_dcMem.CreateCompatibleDC(GetDC());
	m_dcMem.SelectObject(&m_bitmapBgnd);
	int Cx = BOUNDARY_WIDTH  + CUBEWIDTH * GAME_ZONE_WIDTH;
	int Cy = BOUNDARY_HEIGHT + CUBEWIDTH * GAME_ZONE_HEIGHT;
	CRect ControlRect( Cx + CUBEWIDTH * 2 - 10,Cy - 20, Cx  + CUBEWIDTH * 4 + 19,Cy + 10);					     
	m_wndGameControl.Create("Start",BS_OWNERDRAW|WS_TABSTOP|WS_VISIBLE,ControlRect,this,IDC_GAMECONTROL);
 	m_wndGameControl.m_strCaption = "Start";
	m_wndGameControl.SetBitmap(IDB_BTCONTROL);
	m_wndGameControl.SetBKDC(&m_dcMem);
   	CRect MinimizeRect(275,20, 295 , 40);
 	CRect ExitRect(310 ,25, 335,35);
	m_wndGameExit.Create("",BS_OWNERDRAW|WS_TABSTOP|WS_VISIBLE,ExitRect,this,IDC_GAMEEXIT);
    m_wndGameExit.SetBitmap(IDB_BTCLOASE);
	m_wndGameExit.SetBKDC(&m_dcMem);
	m_wndGameMinimize.SetBitmap(IDB_BTMIN);
 	m_wndGameMinimize.SetBKDC(&m_dcMem);
	m_wndGameMinimize.Create("",BS_OWNERDRAW|WS_TABSTOP|WS_VISIBLE,MinimizeRect,this,IDC_GAMEMINIMIZE);
      SetIcon(::LoadIcon(AfxGetApp()->m_hInstance,(LPCSTR)(IDI_MAINFRAME)),TRUE);
	InitialGame();
	m_vtGameZone.resize(GAME_ZONE_HEIGHT);
	for(int i = 0; i < GAME_ZONE_HEIGHT;i++)
		m_vtGameZone[i].resize(GAME_ZONE_WIDTH,false);
}

CGamePlatform::~CGamePlatform()
{
}

BOOL CGamePlatform::PreCreateWindow(CREATESTRUCT& cs)
{
	if( !CFrameWnd::PreCreateWindow(cs) )
		return FALSE;
	cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
	cs.lpszClass = AfxRegisterWndClass(0);

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CGamePlatform diagnostics

#ifdef _DEBUG
void CGamePlatform::AssertValid() const
{
	CFrameWnd::AssertValid();
}

void CGamePlatform::Dump(CDumpContext& dc) const
{
	CFrameWnd::Dump(dc);
}

#endif //_DEBUG
 

BOOL CGamePlatform::OnEraseBkgnd(CDC* pDC) 
{
    CRect rtClient;
	GetClientRect(&rtClient);
	pDC->BitBlt(0,0,rtClient.Width(),rtClient.Height(),&m_dcMem,0,0,SRCCOPY);
	return TRUE;
}
 
bool CGamePlatform::CollisionCheck(DIAMOND diamond, int nPosX, int nPosY)
{
	for(int i = 0; i < diamond.Pos.size(); i ++)
	{
		CPoint pt = DiamondControl.CalcIndex(diamond.Pos[i]);
    	if(pt.x + nPosX <  0 || pt.x + nPosX >= GAME_ZONE_WIDTH ||
		   pt.y + nPosY <  0 || pt.y + nPosY >= GAME_ZONE_HEIGHT)
		    return true;
	    if(m_vtGameZone[pt.y + nPosY][pt.x + nPosX]) 
		   return true;
	}
	return false;
}

void CGamePlatform::FillGameZone(DIAMOND curDiamond)
{
	for(int i = 0; i < curDiamond.Pos.size(); i ++)
	{
		CPoint pt = DiamondControl.CalcIndex(curDiamond.Pos[i]);
		m_vtGameZone[pt.y + curDiamond.nPosY][pt.x +  curDiamond.nPosX] = 1; 
				if(pt.y +  curDiamond.nPosY < m_nDiamondHeight)
					m_nDiamondHeight = pt.y + curDiamond.nPosY;
	}
}
void CGamePlatform::InitialGame()
{
	m_nGameState = GAME_END;
	m_nGameLevel = 0;
	m_nGameScore = 0;
	m_bAccelerateFlag = false;
  	m_vtGameZone.assign(GAME_ZONE_HEIGHT,std::vector<bool>(GAME_ZONE_HEIGHT,false));
	m_nDiamondHeight = GAME_ZONE_HEIGHT;
}
 

void CGamePlatform::OnTimer(UINT nIDEvent) 
{
	switch(m_nGameState) {
		case GAME_START:   GameOnStartStateDeal(); break;
		case GAME_RUN:     GameOnRunStateDeal();   break;
	}
}

void CGamePlatform::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	if(m_nGameState == GAME_RUN)
	{
		switch(nChar){
			case VK_LEFT:	OnLeftKeyPressedDeal();	 break;
			case VK_RIGHT:	OnRightKeyPressedDeal(); break;
			case VK_UP:		OnUpKeyPressedDeal();	 break;
			case VK_DOWN:	OnDownKeyPressedDeal();	 break;
			default: break;
		}
	}
}

void CGamePlatform::DrawDiamond(DIAMOND diamond,bool bFlag)
{
	for(int i = 0; i < diamond.Pos.size(); i ++)
	{
		CPoint pt = DiamondControl.CalcIndex(diamond.Pos[i]);
		DrawCube(pt.x + diamond.nPosX ,pt.y + diamond.nPosY,bFlag);
	}

}

void CGamePlatform::DrawCube(int nCx, int nCy, bool bFlag)
{
	     
	  CRect rtCube(BOUNDARY_WIDTH + nCx * CUBEWIDTH,BOUNDARY_HEIGHT + nCy * CUBEWIDTH,
			  	   BOUNDARY_WIDTH + (nCx + 1) * CUBEWIDTH, BOUNDARY_HEIGHT + (nCy + 1) * CUBEWIDTH);
	  CDC *pDC = GetDC( );
	  switch(bFlag) {
	  case true: {
					pDC->Draw3dRect(&rtCube,RGB(255,232,233),RGB(128,128,128));
					rtCube.DeflateRect(1,1,1,1);
	  				pDC->Draw3dRect(&rtCube,RGB(255,232,233),RGB(128,128,128));
			 	    CFont font;
	                CPen Pen(PS_DASHDOT,1,RGB(255,255,255));
	                font.CreatePointFont (80, _T ("Webdings"));
					CPen *pOldPen =  pDC->SelectObject(&Pen);
	                CFont *pOldFont = pDC->SelectObject(&font);
  	                pDC->SetBkMode(TRANSPARENT);
	                pDC->SetTextColor(RGB(255,255,255));
                 	CString Str;
					Str.Format("%c",'0' + rand()%56);
					pDC->DrawText(Str,&rtCube,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
					pDC->SelectObject(pOldPen);
					pDC->SelectObject(pOldFont);
				 }
		  break;
	  case false:
		  pDC->BitBlt(rtCube.left,rtCube.top,rtCube.Width(),rtCube.Height(),
			  &m_dcMem,rtCube.left,rtCube.top,SRCCOPY);
		 break;
	  }
	  ReleaseDC(pDC);
}
void CGamePlatform::OnGameCtrlClick()
{
	if(m_nGameState == GAME_END)
	{
		InitialGame();
		m_nGameState = GAME_START;
		SetTimer(IDT_GAMETIMER,500 - m_nGameLevel* 50,NULL);
	 	m_wndGameControl.SetCaption("Pause");
  		OnPaint();
	}
	else if(m_nGameState == GAME_RUN)
	{
		m_nGameState = GAME_PAUSE;
		m_wndGameControl.SetCaption("Run");
	}
	else if(m_nGameState == GAME_PAUSE)
	{
		m_nGameState = GAME_RUN;
		m_wndGameControl.SetCaption("Pause");
 	}
	SetFocus();
}

void CGamePlatform::GameOnRunStateDeal()
{
	if(m_nDiamondHeight < 3) {
		m_nGameState = GAME_IDLE;
 	    m_wndGameControl.SetCaption("Start");
	 	m_wndGameControl.SendMessage(WM_LBUTTONDOWN,0,0);
        m_wndGameControl.SendMessage(WM_LBUTTONUP,0,0);
		m_nGameState = GAME_END;

	}
	else {
			int nPosX = DiamondControl.GetCurDiamond().nPosX;
	    	int nPosY = DiamondControl.GetCurDiamond().nPosY;
            if(!CollisionCheck(DiamondControl.GetCurDiamond(),nPosX,nPosY + 1)){
				    DrawDiamond(DiamondControl.GetCurDiamond(),false);
			 	    DiamondControl.SetCurrentDiamondPos(nPosX,nPosY + 1);
					DrawDiamond(DiamondControl.GetCurDiamond(),true);
			}
			else {
				    FillGameZone(DiamondControl.GetCurDiamond());
					DealCollisionResult();
					DrawAchievement();
					CDC *pDC = GetDC();
 					DiamondControl.CreateDiamond();
					DIAMOND nextdiamond = DiamondControl.GetNextDiamond();
					nextdiamond.nPosX = GAME_ZONE_WIDTH + 1;
					nextdiamond.nPosY = GAME_ZONE_HEIGHT/2 - 2;
					FillRectangle(GAME_ZONE_WIDTH + 1,GAME_ZONE_HEIGHT/2 - 2,4,4);
					DrawDiamond(nextdiamond,1);
				}
	}
}

void CGamePlatform::GameOnStartStateDeal()
{
    DiamondControl.CreateDiamond();
	m_nGameState = GAME_RUN;
	FillRectangle(0,0,GAME_ZONE_WIDTH,GAME_ZONE_HEIGHT);
	DrawDiamond(DiamondControl.GetCurDiamond(),1);
	DIAMOND nextdiamond = DiamondControl.GetNextDiamond();
    nextdiamond.nPosX = GAME_ZONE_WIDTH + 1;
	nextdiamond.nPosY = GAME_ZONE_HEIGHT/2 - 2;
	FillRectangle(GAME_ZONE_WIDTH + 1,GAME_ZONE_HEIGHT/2 - 2,4,4);
	DrawDiamond(nextdiamond,1);
}

void CGamePlatform::OnLeftKeyPressedDeal()
{
	int nPosX = DiamondControl.GetCurDiamond().nPosX;
	int nPosY = DiamondControl.GetCurDiamond().nPosY;
	if(!CollisionCheck(DiamondControl.GetCurDiamond(),nPosX - 1,nPosY)){
	    DrawDiamond(DiamondControl.GetCurDiamond(),false);
 	    DiamondControl.SetCurrentDiamondPos(nPosX - 1,nPosY);
		DrawDiamond(DiamondControl.GetCurDiamond(),true);
	}
}

void CGamePlatform::OnRightKeyPressedDeal()
{
	int nPosX = DiamondControl.GetCurDiamond().nPosX;
	int nPosY = DiamondControl.GetCurDiamond().nPosY;
 	if(!CollisionCheck(DiamondControl.GetCurDiamond(),nPosX + 1,nPosY)){
	    DrawDiamond(DiamondControl.GetCurDiamond(),false);
 	    DiamondControl.SetCurrentDiamondPos(nPosX + 1,nPosY);
		DrawDiamond(DiamondControl.GetCurDiamond(),true);
	}
}

void CGamePlatform::OnUpKeyPressedDeal()
{
	DIAMOND tempDiamond = DiamondControl.ChangePos(DiamondControl.GetCurDiamond());
	if(!CollisionCheck(tempDiamond,tempDiamond.nPosX,tempDiamond.nPosY))
	{
		this->DrawDiamond(DiamondControl.GetCurDiamond(),0);
		DiamondControl.SetCurDiamond(tempDiamond);
		this->DrawDiamond(DiamondControl.GetCurDiamond(),1);
	}
}

void CGamePlatform::OnDownKeyPressedDeal()
{
	if(!m_bAccelerateFlag) {
		SetTimer(IDT_GAMETIMER,50,NULL);
		m_bAccelerateFlag = true;
	}
}

void CGamePlatform::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
  
 	CRect GameZoneRect(BOUNDARY_WIDTH,BOUNDARY_HEIGHT,
		BOUNDARY_WIDTH + CUBEWIDTH * GAME_ZONE_WIDTH,
		BOUNDARY_HEIGHT + CUBEWIDTH * GAME_ZONE_HEIGHT);
	GameZoneRect.DeflateRect(-5,-5,-5,-5);
	dc.Draw3dRect(&GameZoneRect,RGB(255,232,233),RGB(128,128,128));
    GameZoneRect.DeflateRect(1,1,1,1);
	dc.Draw3dRect(&GameZoneRect,RGB(255,232,233),RGB(128,128,128));

	CRect rt;
	GetClientRect(&rt);
	CRect NextDiamondRect(BOUNDARY_WIDTH + CUBEWIDTH * GAME_ZONE_WIDTH + 5, BOUNDARY_HEIGHT - 5,
		 rt.right-1,rt.bottom -1);
	GameZoneRect.DeflateRect(-5,-5,-5,-5);
	dc.Draw3dRect(&NextDiamondRect,RGB(255,232,233),RGB(128,128,128));
    NextDiamondRect.DeflateRect(1,1,1,1);
	dc.Draw3dRect(&NextDiamondRect,RGB(255,232,233),RGB(128,128,128));

 	DrawAchievement();
	ReDrawTheCube(GAME_ZONE_HEIGHT - 1);

   
	//Redraw the NextDiamond;
	DIAMOND nextdiamond = DiamondControl.GetNextDiamond();
	nextdiamond.nPosX = GAME_ZONE_WIDTH + 1;
	nextdiamond.nPosY = GAME_ZONE_HEIGHT/2 - 2;
	FillRectangle(GAME_ZONE_WIDTH + 1,GAME_ZONE_HEIGHT/2 - 2,4,4);
	DrawDiamond(nextdiamond,1);
// Do not call CFrameWnd::OnPaint() for painting messages
	if(m_nGameState == GAME_PAUSE) {
		DrawDiamond(DiamondControl.GetCurDiamond(),1);
	}
}

void CGamePlatform::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	SetTimer(IDT_GAMETIMER,500 - m_nGameLevel*50,NULL);
	m_bAccelerateFlag = false;
}

void CGamePlatform::FillRectangle(int nCx, int nCy, int nWidth, int nHeight)
{
	CRect rtFillArea(BOUNDARY_WIDTH + nCx * CUBEWIDTH,BOUNDARY_HEIGHT + nCy * CUBEWIDTH,
		BOUNDARY_WIDTH + (nCx + nWidth)* CUBEWIDTH,BOUNDARY_HEIGHT+(nCy + nHeight) * CUBEWIDTH);
	CDC * pDC =GetDC();
	pDC->BitBlt(rtFillArea.left,rtFillArea.top,rtFillArea.Width(),rtFillArea.Height(),&m_dcMem,rtFillArea.left,rtFillArea.top,SRCCOPY);
}

void CGamePlatform::DealCollisionResult()
{
	int nPosY = DiamondControl.GetCurDiamond().nPosY;
	int nLineNum = 0;
	for(int i = nPosY; i < nPosY + 4; i ++){
 		if(CheckFillUpOrNot(i))	{
			SpecialEffort(i);
	        FillRectangle(0,m_nDiamondHeight,GAME_ZONE_WIDTH,i - m_nDiamondHeight + 1);
			MoveOneLine(i);
			ReDrawTheCube(i);
			nLineNum++;
		}
	}
	m_nGameScore += (nLineNum * 100);
	m_nGameLevel = m_nGameScore / 5000;
}

bool CGamePlatform::CheckFillUpOrNot(int nLineNum)
{
	if(nLineNum < 0 || nLineNum >= GAME_ZONE_HEIGHT)
		return false;
	for(int i = 0; i < GAME_ZONE_WIDTH; i ++){
		if(!m_vtGameZone[nLineNum][i])		
			return false;
		}
 	return true;
}

void CGamePlatform::MoveOneLine(int nLineNum)
{
	if(nLineNum >= 0 && nLineNum < GAME_ZONE_HEIGHT){
		for(int i = nLineNum - 1; i >= m_nDiamondHeight; i --)
			m_vtGameZone[i + 1] = m_vtGameZone[i];
		for(int j = 0; j < GAME_ZONE_WIDTH; j ++)
			m_vtGameZone[m_nDiamondHeight][j] = false;
		m_nDiamondHeight ++;
	}
}

void CGamePlatform::ReDrawTheCube(int nStartNum)
{
	for(int i = nStartNum; i >= m_nDiamondHeight; i--){
		for(int j = 0; j < GAME_ZONE_WIDTH; j ++)
			if(m_vtGameZone[i][j])
			DrawCube(j,i,1);
	}
}

void CGamePlatform::DrawAchievement()
{
	CRect AchievementRect(2, BOUNDARY_HEIGHT + CUBEWIDTH * (GAME_ZONE_HEIGHT) + 6,
							BOUNDARY_WIDTH  +  CUBEWIDTH * GAME_ZONE_WIDTH + 2,
							BOUNDARY_HEIGHT +  CUBEWIDTH * (GAME_ZONE_HEIGHT + 4));

	CDC * pDC = GetDC();
 	pDC->SetTextColor(RGB(255,232,233));
	CString string;
	string.Format("Score: %d   Level:%d",m_nGameScore,m_nGameLevel);
	CFont TextFont;
	TextFont.CreatePointFont (280, _T ("Birch Std"));
	pDC->SelectObject(&TextFont);
	pDC->SetBkMode(TRANSPARENT);
	pDC->BitBlt(AchievementRect.left,AchievementRect.top,AchievementRect.Width(),
		AchievementRect.Height(),&m_dcMem,AchievementRect.left,AchievementRect.top,SRCCOPY);
	pDC->DrawText(string,&AchievementRect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
	ReleaseDC(pDC);
}

void CGamePlatform::SpecialEffort(int nLineNum)
{
 	 CDC * pDC  = GetDC();
	 CPen Pen(PS_DASHDOT,2,RGB(240,240,255));
     CPen *pOldPen = pDC->SelectObject(&Pen);

	for(int i = 0; i < GAME_ZONE_WIDTH; i ++) 
	{
		CRect CubeRect(BOUNDARY_WIDTH + i * CUBEWIDTH,BOUNDARY_HEIGHT + nLineNum * CUBEWIDTH,
			BOUNDARY_WIDTH + (i + 1 )* CUBEWIDTH,BOUNDARY_HEIGHT + (nLineNum +1) * CUBEWIDTH);
		CubeRect.DeflateRect(2,2,2,2);
		for(int j = 0; j < 10; j ++ )
		{
	 		int ncxS = rand()% (CubeRect.Width());
			int ncyS = rand()% (CubeRect.Height());
			int ncxE = rand()% (CubeRect.Width());
			int ncyE = rand()% (CubeRect.Height());
			pDC->MoveTo(CubeRect.left + ncxS,CubeRect.top + ncyS);
			pDC->LineTo(CubeRect.left + ncxE,CubeRect.top + ncyE);
	 	}
		Sleep(10);
	}
   	   pDC->SelectObject(pOldPen);
	   ReleaseDC(pDC);
}

int CGamePlatform::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	ModifyStyle(WS_CAPTION,0);
 	SetWindowPos(NULL,400,80,380,505,0);
 	return 0;
}

UINT CGamePlatform::OnNcHitTest(CPoint point) 
{
	   UINT nHitTest = CFrameWnd::OnNcHitTest (point);
       nHitTest = HTCAPTION;

	return nHitTest;
}

void CGamePlatform::BitmapToRegion()
{
	CDC *pDC = GetDC();
	BITMAP  bmInfo;
	CBitmap bitmap;
	bitmap.LoadBitmap(IDB_BACKGROUND);
	bitmap.GetObject(sizeof(bmInfo),&bmInfo);
	CRect RectRgn(0,0,bmInfo.bmWidth,bmInfo.bmHeight);
 	CDC dcMem;
	dcMem.CreateCompatibleDC(pDC);
	dcMem.SelectObject(&bitmap);
	
	CRgn bmpRGN;
 	bmpRGN.CreateRectRgn(0,0,RectRgn.Width(),RectRgn.Height());
 	CRgn tempRgn;
	for(int i = 0; i < bmInfo.bmWidth; i ++)
		for(int j = 0; j < bmInfo.bmHeight; j++)
		{
			if(dcMem.GetPixel(i,j) == RGB(0,0,0))
			{
				tempRgn.CreateRectRgn(i,j,i+1,j+1);
				bmpRGN.CombineRgn(&bmpRGN,&tempRgn,RGN_XOR);
				tempRgn.DeleteObject();
			}
		}
    SetWindowRgn(bmpRGN,true);
 	ReleaseDC(pDC);
}