// CChildView window
#define ROW 15
#define COL 10
#define NorTimer 1
#define QuiTimer 2
#define BoxWidth 30
struct BOXPOS
{
int row;
int col;
};
class CChildView : public CWnd
{
// Construction
public:
CChildView();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CChildView)
protected:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CChildView();
// Generated message map functions
protected:
CRect m_rcGameBoard;
CRect m_rcNextBoxWnd;
COLORREF m_crDBoxColor;
COLORREF m_crSBoxColor;
UINT m_nCurColor;
int m_nRunNorTimer;
int m_nRunQuiTimer;
int m_nScore;
int m_nBaseScore;
int MaxScore;
static const int PLevScore[3];
static const int PLevTimer[4];
int m_nDown;
int m_nKind;
int m_nModel;
int m_nNextKind;
int m_nNextModel;
int m_nNewModel;
int m_nOrigin;
int m_nOffset;
UINT m_nLevel;
UINT m_nTimerKey;
COLORREF BoxColor[4];
int Visited[ROW][COL];
CRect SubBox[ROW][COL];
CRect DynamicBox[4];
CRect NextBox[4][4];
BOXPOS DBoxPos[4];
BOXPOS NBoxPos[4];
BOXPOS NewDBoxPos[4];
BOOL m_bStart;
void GetModel(BOXPOS BoxPos[],int nKind,int nModel);
void DrawDynamicBox(CDC *pDC);
void DrawStaticBox(CDC *pDC);
void DrawNextBox(CDC *pDC);
void DrawGameBorder(CDC *pDC);
void TimerProc();
void LevelProc(int nLevel);
void ClsUnionLine(int nRow);
void GameOver();
void StopGame();
void InitGame();
void IsEdge(int &nLeftEdge,int &nRightEdge);
void GetDBoxPos(BOXPOS BoxPos[],int i,int &nRow,int &nCol);
void GetNBoxPos(int i,int &nRow,int &nCol);
BOOL CanTransForm();
void StaticBoxProc();
void PassLevel();
void GetRecord();
void SaveRecord();
//{{AFX_MSG(CChildView)
afx_msg void OnPaint();
afx_msg void OnKeyDown(UINT nChar,UINT nRepCnt,UINT nFlags);
afx_msg void OnKeyUp(UINT nChar,UINT nRepCnt,UINT nFlags);
afx_msg void OnTimer(UINT nTimerID);
afx_msg void OnStartGame();
afx_msg void OnStopGame();
afx_msg void OnSelectLevel(UINT nID);
afx_msg void OnUpdateLevelUI(CCmdUI *pCmdUI);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
// ChildView.cpp : implementation of the CChildView class
//
#include "stdafx.h"
#include "Russia.h"
#include "ChildView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CChildView
CChildView::CChildView()
{
m_rcGameBoard = CRect (20,20,320,470);
m_rcNextBoxWnd=CRect(360,20,480,140);
BoxColor[0]=RGB(230,0,0);
BoxColor[1]=RGB(51,51,0);
BoxColor[2]=RGB(51,204,204);
BoxColor[3]=RGB(204,153,255);
m_nCurColor=0;
m_crDBoxColor=BoxColor[m_nCurColor];
m_crSBoxColor=RGB(192,192,192);
m_nCurColor=0;
m_nOrigin=5;
m_bStart=FALSE;
m_nScore=0;
m_nLevel=1;
int nLeft,nTop;
for(int i=0;i<ROW;i++)
for(int j=0;j<COL;j++)
{
nLeft=m_rcGameBoard.left;
nTop=m_rcGameBoard.top;
SubBox[i][j]=CRect(nLeft+BoxWidth*j,nTop+BoxWidth*i,
nLeft+BoxWidth*(j+1),nTop+BoxWidth*(i+1));
}
for(i=0;i<4;i++)
for(int j=0;j<4;j++)
{
nLeft=m_rcNextBoxWnd.left;
nTop=m_rcNextBoxWnd.top;
NextBox[i][j]=CRect(nLeft+BoxWidth*j,nTop+BoxWidth*i,
nLeft+BoxWidth*(j+1),nTop+BoxWidth*(i+1));
}
GetRecord();
}
CChildView::~CChildView()
{
}
BEGIN_MESSAGE_MAP(CChildView,CWnd )
ON_WM_PAINT()
ON_WM_KEYDOWN()
ON_WM_KEYUP()
ON_WM_TIMER()
//{{AFX_MSG_MAP(CChildView)
ON_WM_PAINT()
ON_COMMAND(ID_GAME_START, OnStartGame)
ON_COMMAND(ID_STOP_GAME, OnStopGame)
ON_COMMAND_RANGE(ID_LEVEL1,ID_LEVEL4,OnSelectLevel)
ON_UPDATE_COMMAND_UI_RANGE(ID_LEVEL1,ID_LEVEL4,OnUpdateLevelUI)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CChildView message handlers
const int CChildView::PLevScore[3]={500,1000,1500};
const int CChildView::PLevTimer[4]={500,300,300,200};
BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
{
if (!CWnd::PreCreateWindow(cs))
return FALSE;
cs.dwExStyle |= WS_EX_CLIENTEDGE;
cs.style &= ~WS_BORDER;
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL);
return TRUE;
}
void CChildView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CWnd::OnPaint() for painting messages
CDC MemDC;
CBitmap bitmap;
MemDC.CreateCompatibleDC (NULL);
bitmap.CreateCompatibleBitmap (&dc,600,700);
CBitmap *pOldbit=MemDC.SelectObject (&bitmap);
MemDC.SetBkMode (TRANSPARENT);
DrawGameBorder(&MemDC);
DrawDynamicBox(&MemDC);
DrawStaticBox(&MemDC);
DrawNextBox(&MemDC);
dc.BitBlt (0,0,600,700,&MemDC,0,0,SRCCOPY);
bitmap.DeleteObject ();
MemDC.DeleteDC ();
}
void CChildView::DrawGameBorder(CDC *pDC)
{
pDC->FillSolidRect (0,0,600,700,RGB(0,0,0));
pDC->DrawEdge (m_rcGameBoard,EDGE_SUNKEN,BF_RECT);
pDC->DrawEdge (m_rcNextBoxWnd,EDGE_SUNKEN,BF_RECT);
CFont font;
font.CreatePointFont(200,_T("Arial"));
CFont *pOldFont=pDC->SelectObject (&font);
pDC->SetTextColor (RGB(255,0,0));
CRect screct1(360,280,480,310);
CRect screct2(360,320,480,350);
CRect screct3(360,380,480,410);
CRect screct4(360,420,480,450);
CRect screct5(360,220,480,250);
CString score,maxscore,level;
score.Format ("%d",m_nScore);
maxscore.Format ("%d",MaxScore);
level.Format ("第%d关",m_nLevel);
pDC->DrawText (_T("得分"),-1,&screct1,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
pDC->DrawText (_T(score),-1,&screct2,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
pDC->DrawText (_T("最高分"),-1,&screct3,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
pDC->DrawText (_T(maxscore),-1,&screct4,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
pDC->DrawText (_T(level),-1,&screct5,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
pDC->SelectObject (pOldFont);
}
void CChildView::TimerProc()
{
int nRow,nCol;
for(int i=0;i<4;i++)
{
GetDBoxPos(DBoxPos,i,nRow,nCol);
if(nRow>=ROW-1||Visited[nRow+1][nCol]==1)
{
for(int j=0;j<4;j++)
{
GetDBoxPos(DBoxPos,j,nRow,nCol);
Visited[nRow][nCol]=1;
}
m_nKind=m_nNextKind;
m_nModel=m_nNextModel;
m_nNextKind=rand()%7;
m_nNextModel=rand()%4;
m_nOffset=0;
m_nDown=0;
m_nBaseScore=10;
StaticBoxProc();
LevelProc(m_nLevel);
Invalidate(FALSE);
return;
}
}
m_nDown++;
Invalidate(FALSE);
}
void CChildView::LevelProc (int nLevel)
{
switch(nLevel)
{
case 1:
case 2:
break;
case 3:
case 4:
int tmp;
for(int i=ROW-1;i>=0;i--)
{
tmp=0;
for(int j=COL-1;j>=0;j--)
{
if(Visited[i][j]==1)
{
if(j==COL-1)
{
tmp=Visited[i][j];
Visited[i][j]=0;
}
else
{
Visited[i][j+1]=Visited[i][j];
Visited[i][j]=0;
}
}
}
Visited[i][0]=tmp;
}
break;
}
}
void CChildView::DrawDynamicBox (CDC *pDC)
{
CDC MemDC1;
MemDC1.CreateCompatibleDC (pDC);
CBitmap kulou;
kulou.LoadBitmap(IDB_BOX);
CBitmap *pOldmap=MemDC1.SelectObject (&kulou);
GetModel(DBoxPos,m_nKind,m_nModel);
int nRow,nCol;
CRect rect;
if(m_bStart)
for(int i=0;i<4;i++)
{
GetDBoxPos(DBoxPos,i,nRow,nCol);
rect=SubBox[nRow][nCol];
pDC->StretchBlt(rect.left,rect.top,
BoxWidth,BoxWidth,&MemDC1,0,0,50,50,SRCCOPY);
}
MemDC1.SelectObject (pOldmap);
kulou.DeleteObject ();
MemDC1.DeleteDC ();
}
void CChildView::DrawStaticBox (CDC *pDC)
{
CDC MemDC1;
MemDC1.CreateCompatibleDC (pDC);
CBitmap kulou;
kulou.LoadBitmap(IDB_BOX);
CBitmap *pOldmap=MemDC1.SelectObject (&kulou);
CRect rect;
for(int i=0;i<ROW;i++)
for(int j=0;j<COL;j++)
if(Visited[i][j]==1)
{
rect=SubBox[i][j];
pDC->StretchBlt(rect.left,rect.top,
BoxWidth,BoxWidth,&MemDC1,0,0,50,50,SRCCOPY);
}
MemDC1.SelectObject (pOldmap);
kulou.DeleteObject ();
MemDC1.DeleteDC ();
}
void CChildView::DrawNextBox (CDC *pDC)
{
CDC MemDC1;
MemDC1.CreateCompatibleDC (pDC);
CBitmap kulou;
kulou.LoadBitmap(IDB_BOX);
CBitmap *pOldmap=MemDC1.SelectObject (&kulou);
GetModel(NBoxPos,m_nNextKind,m_nNextModel);
int nRow,nCol;
CRect rect;
if(m_bStart)
for(int i=0;i<4;i++)
{
GetNBoxPos(i,nRow,nCol);
rect=NextBox[nRow][nCol];
pDC->StretchBlt(rect.left,rect.top,
BoxWidth,BoxWidth,&MemDC1,0,0,50,50,SRCCOPY);
}
MemDC1.SelectObject (pOldmap);
kulou.DeleteObject ();
MemDC1.DeleteDC ();
}
void CChildView::StaticBoxProc ()
{
int nIsUnionLine;
for(int i=ROW-1;i>=0;i--)
{
nIsUnionLine=1;
for(int j=COL-1;j>=0;j--)
{
if(Visited[i][j]==0)
nIsUnionLine=0;
else if(i<=0)
GameOver();
}
if(nIsUnionLine)
{
ClsUnionLine(i);
break;
}
}
}
void CChildView::ClsUnionLine (int nRow)
{
m_nScore+=m_nBaseScore;
if(m_nScore>=PLevScore[m_nLevel-1]&&m_nLevel<4)
PassLevel();
m_nBaseScore+=10;
for(int nCol=0;nCol<COL;nCol++)
Visited[nRow][nCol]=0;
for(int i=nRow-1;i>=0;i--)
for(int j=COL-1;j>=0;j--)
if(Visited[i][j]==1)
if(i<ROW&&Visited[i+1][j]!=1)
{
Visited[i][j]=0;
Visited[i+1][j]=1;
}
StaticBoxProc();
}
void CChildView::PassLevel()
{
m_nLevel++;
SetTimer(NorTimer,PLevTimer[m_nLevel-1],NULL);
InitGame();
}
void CChildView::OnTimer (UINT nTimerID)
{
if(nTimerID==NorTimer&&m_nRunNorTimer)
TimerProc ();
if(nTimerID==QuiTimer&&m_nRunQuiTimer)
TimerProc ();
}
void CChildView::OnKeyDown (UINT nChar,UINT nRepCnt,UINT nFlags)
{
int nLeftEdge,nRightEdge;
switch(nChar)
{
case VK_RIGHT:
IsEdge(nLeftEdge,nRightEdge);
if(!nRightEdge)
{
m_nOffset++;
Invalidate(FALSE);
}
break;
case VK_LEFT:
IsEdge(nLeftEdge,nRightEdge);
if(!nLeftEdge)
{
m_nOffset--;
Invalidate(FALSE);
}
break;
case VK_UP:
m_nNewModel=m_nModel;
m_nNewModel=(m_nNewModel<3)?++m_nNewModel:0;
if(CanTransForm())
{ m_nModel=m_nNewModel;
Invalidate(FALSE);
}
break;
case VK_DOWN:
m_nRunQuiTimer=1;
m_nRunNorTimer=0;
break;
default:
break;
}
}
void CChildView::OnKeyUp (UINT nChar,UINT nRepCnt,UINT nFlags)
{
switch(nChar)
{
case VK_DOWN:
m_nRunQuiTimer=0;
m_nRunNorTimer=1;
break;
default:
break;
}
}
void CChildView::GameOver()
{
StopGame();
CString string=_T("游戏结束!");
MessageBox (string,_T("Game Over"),MB_ICONEXCLAMATION|MB_OK);
Invalidate(FALSE);
}
void CChildView::StopGame ()
{
KillTimer(NorTimer);
KillTimer(QuiTimer);
::ZeroMemory(&Visited[0][0],ROW*COL*sizeof(int));
m_bStart=FALSE;
if(m_nScore>MaxScore)
{ MaxScore=m_nScore; SaveRecord(); }
}
void CChildView::IsEdge (int &nLeftEdge,int &nRightEdge)
{
int nRow,nCol;
nLeftEdge=0;nRightEdge=0;
for(int i=0;i<4;i++)
{
GetDBoxPos(DBoxPos,i,nRow,nCol);
if(nCol<=0||Visited[nRow][nCol-1]==1)
nLeftEdge=1;
if(nCol>=COL-1||Visited[nRow][nCol+1]==1)
nRightEdge=1;
}
}
void CChildView::GetDBoxPos (BOXPOS BoxPos[],int i,int &nRow,int &nCol)
{
nRow=BoxPos[i].row +m_nDown;
nCol=BoxPos[i].col +m_nOrigin+m_nOffset;
}
void CChildView::GetNBoxPos(int i,int &nRow,int &nCol)
{
nRow=NBoxPos[i].row;
nCol=NBoxPos[i].col+2;
}
BOOL CChildView::CanTransForm ()
{
int nRow,nCol;
GetModel(NewDBoxPos,m_nKind,m_nNewModel);
for(int i=0;i<4;i++)
{
GetDBoxPos(NewDBoxPos,i,nRow,nCol);
if(nRow>ROW-1||nCol<0||nCol>COL-1||
Visited[nRow][nCol]==1)
return FALSE;
}
return TRUE;
}
void CChildView::GetModel (BOXPOS BoxPos[],int nKind,int nModel)
{
switch(nKind)
{
case 0:
switch(nModel)
{
case 0:
case 2:
BoxPos[0].row =0; BoxPos[0].col =-2;
BoxPos[1].row =0; BoxPos[1].col =-1;
BoxPos[2].row =0; BoxPos[2].col =0;
BoxPos[3].row =0; BoxPos[3].col =1;
break;
case 1:
case 3:
BoxPos[0].row =0; BoxPos[0].col =0;
BoxPos[1].row =1; BoxPos[1].col =0;
BoxPos[2].row =2; BoxPos[2].col =0;
BoxPos[3].row =3; BoxPos[3].col =0;
break;
default:
break;
}
break;
case 1:
switch(nModel)
{
case 0:
BoxPos[0].row =0; BoxPos[0].col =-1;
BoxPos[1].row =0; BoxPos[1].col =0;
BoxPos[2].row =0; BoxPos[2].col =1;
BoxPos[3].row =1; BoxPos[3].col =0;
break;
case 1:
BoxPos[0].row =0; BoxPos[0].col =0;
BoxPos[1].row =1; BoxPos[1].col =0;
BoxPos[2].row =2; BoxPos[2].col =0;
BoxPos[3].row =1; BoxPos[3].col =1;
break;
case 2:
BoxPos[0].row =0; BoxPos[0].col =0;
BoxPos[1].row =1; BoxPos[1].col =-1;
BoxPos[2].row =1; BoxPos[2].col =0;
BoxPos[3].row =1; BoxPos[3].col =1;
break;
case 3:
BoxPos[0].row =0; BoxPos[0].col =0;
BoxPos[1].row =1; BoxPos[1].col =0;
BoxPos[2].row =2; BoxPos[2].col =0;
BoxPos[3].row =1; BoxPos[3].col =-1;
break;
default:
break;
}
break;
case 2:
switch(nModel)
{
case 0:
BoxPos[0].row =0; BoxPos[0].col =0;
BoxPos[1].row =0; BoxPos[1].col =-1;
BoxPos[2].row =1; BoxPos[2].col =0;
BoxPos[3].row =2; BoxPos[3].col =0;
break;
case 1:
BoxPos[0].row =0; BoxPos[0].col =-1;
BoxPos[1].row =0; BoxPos[1].col =0;
BoxPos[2].row =0; BoxPos[2].col =1;
BoxPos[3].row =1; BoxPos[3].col =-1;
break;
case 2:
BoxPos[0].row =0; BoxPos[0].col =-1;
BoxPos[1].row =1; BoxPos[1].col =-1;
BoxPos[2].row =2; BoxPos[2].col =-1;
BoxPos[3].row =2; BoxPos[3].col =0;
break;
case 3:
BoxPos[0].row =0; BoxPos[0].col =1;
BoxPos[1].row =1; BoxPos[1].col =1;
BoxPos[2].row =1; BoxPos[2].col =0;
BoxPos[3].row =1; BoxPos[3].col =-1;
break;
default:
break;
}
break;
case 3:
switch(nModel)
{
case 0:
BoxPos[0].row =0; BoxPos[0].col =-1;
BoxPos[1].row =0; BoxPos[1].col =0;
BoxPos[2].row =1; BoxPos[2].col =-1;
BoxPos[3].row =2; BoxPos[3].col =-1;
break;
case 1:
BoxPos[0].row =0; BoxPos[0].col =-1;
BoxPos[1].row =1; BoxPos[1].col =-1;
BoxPos[2].row =1; BoxPos[2].col =0;
BoxPos[3].row =1; BoxPos[3].col =1;
break;
case 2:
BoxPos[0].row =0; BoxPos[0].col =0;
BoxPos[1].row =1; BoxPos[1].col =0;
BoxPos[2].row =2; BoxPos[2].col =0;
BoxPos[3].row =2; BoxPos[3].col =-1;
break;
case 3:
BoxPos[0].row =0; BoxPos[0].col =-1;
BoxPos[1].row =0; BoxPos[1].col =0;
BoxPos[2].row =0; BoxPos[2].col =1;
BoxPos[3].row =1; BoxPos[3].col =1;
break;
default:
break;
}
break;
case 4:
switch(nModel)
{
case 0:
case 2:
BoxPos[0].row =0; BoxPos[0].col =-1;
BoxPos[1].row =0; BoxPos[1].col =0;
BoxPos[2].row =1; BoxPos[2].col =0;
BoxPos[3].row =1; BoxPos[3].col =1;
break;
case 1:
case 3:
BoxPos[0].row =0; BoxPos[0].col =0;
BoxPos[1].row =1; BoxPos[1].col =0;
BoxPos[2].row =1; BoxPos[2].col =-1;
BoxPos[3].row =2; BoxPos[3].col =-1;
break;
default:
break;
}
break;
case 5:
switch(nModel)
{
case 0:
case 2:
BoxPos[0].row =0; BoxPos[0].col =0;
BoxPos[1].row =0; BoxPos[1].col =1;
BoxPos[2].row =1; BoxPos[2].col =0;
BoxPos[3].row =1; BoxPos[3].col =-1;
break;
case 1:
case 3:
BoxPos[0].row =0; BoxPos[0].col =-1;
BoxPos[1].row =1; BoxPos[1].col =-1;
BoxPos[2].row =1; BoxPos[2].col =0;
BoxPos[3].row =2; BoxPos[3].col =0;
default:
break;
}
break;
case 6:
BoxPos[0].row =0; BoxPos[0].col =-1;
BoxPos[1].row =0; BoxPos[1].col =0;
BoxPos[2].row =1; BoxPos[2].col =-1;
BoxPos[3].row =1; BoxPos[3].col =0;
break;
default:
break;
}
}
void CChildView::OnStartGame()
{
// TODO: Add your command handler code here
InitGame();
m_nScore=0;
m_nRunQuiTimer=0;
m_nRunNorTimer=1;
m_bStart=TRUE;
SetTimer(NorTimer,PLevTimer[m_nLevel-1],NULL);
SetTimer(QuiTimer,20,NULL);
Invalidate(FALSE);
}
void CChildView::InitGame ()
{
::ZeroMemory(&Visited[0][0],ROW*COL*sizeof(int));
srand((unsigned)time(NULL));
m_nOffset=0;
m_nDown=0;
m_nNextKind=rand()%7;
m_nNextModel=rand()%4;
m_nKind=m_nNextKind;
m_nModel=m_nNextModel;
m_nNextKind=rand()%7;
m_nNextModel=rand()%4;
}
void CChildView::OnStopGame()
{
// TODO: Add your command handler code here
StopGame();
Invalidate(FALSE);
}
void CChildView::GetRecord ()
{
FILE *pf;
if((pf=fopen("record.dat","r"))==NULL)
TRACE0("Can't open file record.dat/n");
fscanf(pf,"%d",&MaxScore);
fclose(pf);
}
void CChildView::SaveRecord ()
{
FILE *pf;
if((pf=fopen("record.dat","w"))==NULL)
TRACE0("Can't open file record.dat/n");
fprintf(pf,"%d",MaxScore);
fclose(pf);
}
void CChildView::OnSelectLevel (UINT nID)
{
m_nLevel=nID-ID_LEVEL1+1;
InvalidateRect(CRect(360,220,480,250),FALSE);
}
void CChildView::OnUpdateLevelUI (CCmdUI *pCmdUI)
{
pCmdUI->SetCheck(pCmdUI->m_nID-ID_LEVEL1+1==m_nLevel);
}
游戏界面: