📄 rusblockview.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 + -