最近在看一个用MFC编程的俄罗斯方块。其中有个别代码看不懂:#define MAXCOM 7 // 部件数
#define WIDE 13 // 游戏区域宽
#define HIGH 26 // 高
#define SIZE 12 // 组成游戏区域的方格大小
#define TOP 50 // 游戏左上角坐标
#define LEFT 50
#define EASY 500 // 游戏难度
#define NORMAL 300
#define HARD 200
typedef struct tagComponet
{
int intComID; // 部件的ID号
int intDimension; // 存储该部件所需的数组维数
int * pintArray; // 指向存储该部件的数组
} Componet;class CRusBlockView:public CView
{
//此处略去若干行系统生成的代码
private:
int m_intComID; // 当前下落的部件
int m_intState [HIGH] [WIDE]; // 当前状态
Componet m_Componets [MAXCOM]; // 所有部件的内部表示
int m_intScore; // 分数
int m_intLevel;
Componet m_CurrentCom; // 当前的部件
POINT ptIndex; // 部件数组在全局数组中的索引
void NewComponet (void); // 产生一个新的部件
bool CanDown (void); // 是否还可以下落
void MyInvalidateRect (POINT ptStart, int intDimension); // 刷新函数
void Disappear (void); // 消去行
bool CheckFail (void); // 判断游戏是否结束
bool CanRotate (void); // 是否还可以旋转
bool CanLeft (void); // 是否还可以左移
bool CanRight (void); // 是否还可以右移
bool CanNew ( );//检查是否有足够的空位显示新的部件,否则游戏结束
}
void CRusBlockView::OnDraw(CDC* pDC)
{
CRusBlockDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
// 画游戏区域
CBrush brushBK (RGB (0, 0, 0) );
CBrush * pbrushOld = pDC -> SelectObject (&brushBK);
pDC -> Rectangle (LEFT, TOP, LEFT + WIDE * SIZE,TOP + HIGH * SIZE); // 画不能移动的方块
CBrush brushStick (RGB (0,255,0) );
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 (255, 0, 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);
}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);
}
void CRusBlockView::MyInvalidateRect (POINT ptStrat, int intDimension)
{
// 刷新了一个以ptStart为左上角,长度为intDimension的正方区域
// 同时注意判断不要越出游戏区域
int x1 = LEFT +ptStrat. y * SIZE;
x1 = x1 > LEFT? x1: LEFT;
int y1 = TOP + ptStrat. x * SIZE;
y1 = y1 > TOP? y1: TOP;
int x2 = LEFT + (ptStrat. y + intDimension) * SIZE;
x2 = x2 > LEFT + WIDE * SIZE? LEFT + WIDE * SIZE: x2;
int y2 = TOP + (ptStrat. x + intDimension) * SIZE;
y2 = y2 > TOP + HIGH * SIZE? TOP + HIGH * SIZE: y2;
InvalidateRect (CRect (x1, y1, x2, y2) );
}
上面的void CRusBlockView::OnTimer(UINT nIDEvent) 中的我看不懂:
// 擦除
MyInvalidateRect (ptIndex, intDimension);[color=#00FF00]这个语句调用怎么会是擦除呢?应该是在指定的矩形区域里重新绘制图形啊? // 下落
ptIndex. x ++;
// 显示新位置上的部件
MyInvalidateRect (ptIndex, intDimension);[/color]
#define WIDE 13 // 游戏区域宽
#define HIGH 26 // 高
#define SIZE 12 // 组成游戏区域的方格大小
#define TOP 50 // 游戏左上角坐标
#define LEFT 50
#define EASY 500 // 游戏难度
#define NORMAL 300
#define HARD 200
typedef struct tagComponet
{
int intComID; // 部件的ID号
int intDimension; // 存储该部件所需的数组维数
int * pintArray; // 指向存储该部件的数组
} Componet;class CRusBlockView:public CView
{
//此处略去若干行系统生成的代码
private:
int m_intComID; // 当前下落的部件
int m_intState [HIGH] [WIDE]; // 当前状态
Componet m_Componets [MAXCOM]; // 所有部件的内部表示
int m_intScore; // 分数
int m_intLevel;
Componet m_CurrentCom; // 当前的部件
POINT ptIndex; // 部件数组在全局数组中的索引
void NewComponet (void); // 产生一个新的部件
bool CanDown (void); // 是否还可以下落
void MyInvalidateRect (POINT ptStart, int intDimension); // 刷新函数
void Disappear (void); // 消去行
bool CheckFail (void); // 判断游戏是否结束
bool CanRotate (void); // 是否还可以旋转
bool CanLeft (void); // 是否还可以左移
bool CanRight (void); // 是否还可以右移
bool CanNew ( );//检查是否有足够的空位显示新的部件,否则游戏结束
}
void CRusBlockView::OnDraw(CDC* pDC)
{
CRusBlockDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
// 画游戏区域
CBrush brushBK (RGB (0, 0, 0) );
CBrush * pbrushOld = pDC -> SelectObject (&brushBK);
pDC -> Rectangle (LEFT, TOP, LEFT + WIDE * SIZE,TOP + HIGH * SIZE); // 画不能移动的方块
CBrush brushStick (RGB (0,255,0) );
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 (255, 0, 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);
}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);
}
void CRusBlockView::MyInvalidateRect (POINT ptStrat, int intDimension)
{
// 刷新了一个以ptStart为左上角,长度为intDimension的正方区域
// 同时注意判断不要越出游戏区域
int x1 = LEFT +ptStrat. y * SIZE;
x1 = x1 > LEFT? x1: LEFT;
int y1 = TOP + ptStrat. x * SIZE;
y1 = y1 > TOP? y1: TOP;
int x2 = LEFT + (ptStrat. y + intDimension) * SIZE;
x2 = x2 > LEFT + WIDE * SIZE? LEFT + WIDE * SIZE: x2;
int y2 = TOP + (ptStrat. x + intDimension) * SIZE;
y2 = y2 > TOP + HIGH * SIZE? TOP + HIGH * SIZE: y2;
InvalidateRect (CRect (x1, y1, x2, y2) );
}
上面的void CRusBlockView::OnTimer(UINT nIDEvent) 中的我看不懂:
// 擦除
MyInvalidateRect (ptIndex, intDimension);[color=#00FF00]这个语句调用怎么会是擦除呢?应该是在指定的矩形区域里重新绘制图形啊? // 下落
ptIndex. x ++;
// 显示新位置上的部件
MyInvalidateRect (ptIndex, intDimension);[/color]
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货