最近在看一个用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]