⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit1.cpp

📁 自编小俄罗斯方块
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    m_isBottom = FALSE;
    ActiveIsBottom();

    InvalidateCurrent();

    //在屏幕右边显示下一次将会出来的方块的模样
    RectStatusToNextStatus( m_inextStatus );
    TRect rect(m_iStartY+320, m_iStartX, m_iStartY+440, m_iStartX+160);
    InvalidateRect(Handle,&rect,false);

    //判断游戏是否已结束: 碰了底,且第1行有小方块
    if (m_isBottom)
      for (i=0;i<m_iCol;i++)
        if (GameStatus[0][i])
        {
          Timer1->Enabled=false;
          Application->MessageBox("游戏已结束!","提示",MB_OK);
          for (j=0;j<m_iRow;j++)
            for (k=0;k<m_iCol;k++)
              GameStatus[j][k]=0;
          Invalidate();
          m_bGameEnd = TRUE;
          break;
        }
  }
  else  //当前方块下降
  {
    RectDown();
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
 switch(Key)
  {
  case 'a':
  case 'A':
  case VK_LEFT:
      RectArrow(LEFT);
      break;
  case 'd':
  case 'D':
  case VK_RIGHT:
      RectArrow(RIGHT);
      break;
  case 's':
  case 'S':
  case VK_UP:
      RectChange();
      break;
  case 'x':
  case 'X':
  case VK_DOWN:
      RectArrow(DOWN);
      break;
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::StartClick(TObject *Sender)
{
  if (!m_bGamePaush)  //如果不是游戏暂停状态,则必须作些初始工作
  {
    m_bGameEnd = FALSE;
    //总分值清零, 并显示总分记分牌
    m_iPerformance = 0;

    //显示当前的区域及游戏级别的汉字描述
    CurrentAreaAndLevel();

    TRect rect(m_iStartY, m_iStartX, m_iStartY+440, m_iStartX+370);
    InvalidateRect(Handle,&rect,false);
  }

  m_bGamePaush = FALSE;
  Timer1->Enabled=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::PauseClick(TObject *Sender)
{
  m_bGamePaush = TRUE;

  Timer1->Enabled=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::StopClick(TObject *Sender)
{
  m_bGameEnd = TRUE;

  int i,j;
  for (i=0;i<m_iRow;i++)
    for (j=0;j<m_iCol;j++)
      GameStatus[i][j]=0;

  TRect rect(m_iStartY, m_iStartX, m_iStartY+440, m_iStartX+370);
  InvalidateRect(Handle,&rect,false);

  m_bGamePaush = FALSE;  //清除游戏暂停状态
  Timer1->Enabled=false;
}
//---------------------------------------------------------------------------
/* * * * * * * * * * * * * * * * * * * * * *
* 内部函数:产生一个最大值不大于指定值的随机整数(Random)
* 参数:MaxNumber : 随机数的上限
* 返回值: 产生的随机数
* * * * * * * * * * * * * * * * * * * * * */
int TForm1::Random(int MaxNumber)
{
  int currentClock = (int)clock();
  srand(currentClock);
  return (rand() % MaxNumber);
}
//---------------------------------------------------------------------------
/* * * * * * * * * * * * * * * * * * * * * *
* 内部函数:将当前动态数组中的数据反映到大数组中
* * * * * * * * * * * * * * * * * * * * * */
void TForm1::ActiveStatusToGameStatus()
{
  int x1,x2,x3,x4,y1,y2,y3,y4;
  x1 = ActiveStatus[0][0];
  x2 = ActiveStatus[1][0];
  x3 = ActiveStatus[2][0];
  x4 = ActiveStatus[3][0];
  y1 = ActiveStatus[0][1];
  y2 = ActiveStatus[1][1];
  y3 = ActiveStatus[2][1];
  y4 = ActiveStatus[3][1];
  GameStatus[x1][y1]=1;
  GameStatus[x2][y2]=1;
  GameStatus[x3][y3]=1;
  GameStatus[x4][y4]=1;
}
//---------------------------------------------------------------------------
/* * * * * * * * * * * * * * * * * * * * * *
* 内部函数:初始掉落时,将根据方块的样式决定当前动态数组的值
* * * * * * * * * * * * * * * * * * * * * */
void TForm1::RectStatusToActiveStatus(int m_which)
{
  switch(m_which)
  {
  case 1:
    ActiveStatus[0][0] = 0;
    ActiveStatus[0][1] = 5;
    ActiveStatus[1][0] = 1;
    ActiveStatus[1][1] = 5;
    ActiveStatus[2][0] = 2;
    ActiveStatus[2][1] = 5;
    ActiveStatus[3][0] = 3;
    ActiveStatus[3][1] = 5;
    break;
  case 2:
    ActiveStatus[0][0] = 0;
    ActiveStatus[0][1] = 5;
    ActiveStatus[1][0] = 1;
    ActiveStatus[1][1] = 5;
    ActiveStatus[2][0] = 0;
    ActiveStatus[2][1] = 6;
    ActiveStatus[3][0] = 1;
    ActiveStatus[3][1] = 6;
    break;
  case 3:
    ActiveStatus[0][0] = 1;
    ActiveStatus[0][1] = 4;
    ActiveStatus[1][0] = 0;
    ActiveStatus[1][1] = 5;
    ActiveStatus[2][0] = 1;
    ActiveStatus[2][1] = 5;
    ActiveStatus[3][0] = 1;
    ActiveStatus[3][1] = 6;
    break;
  case 4:
    ActiveStatus[0][0] = 0;
    ActiveStatus[0][1] = 5;
    ActiveStatus[1][0] = 1;
    ActiveStatus[1][1] = 5;
    ActiveStatus[2][0] = 1;
    ActiveStatus[2][1] = 6;
    ActiveStatus[3][0] = 2;
    ActiveStatus[3][1] = 6;
    break;
  case 5:
    ActiveStatus[0][0] = 1;
    ActiveStatus[0][1] = 5;
    ActiveStatus[1][0] = 2;
    ActiveStatus[1][1] = 5;
    ActiveStatus[2][0] = 0;
    ActiveStatus[2][1] = 6;
    ActiveStatus[3][0] = 1;
    ActiveStatus[3][1] = 6;
    break;
  case 6:
    ActiveStatus[0][0] = 0;
    ActiveStatus[0][1] = 5;
    ActiveStatus[1][0] = 0;
    ActiveStatus[1][1] = 6;
    ActiveStatus[2][0] = 1;
    ActiveStatus[2][1] = 6;
    ActiveStatus[3][0] = 2;
    ActiveStatus[3][1] = 6;
    break;
  case 7:
    ActiveStatus[0][0] = 0;
    ActiveStatus[0][1] = 5;
    ActiveStatus[1][0] = 1;
    ActiveStatus[1][1] = 5;
    ActiveStatus[2][0] = 2;
    ActiveStatus[2][1] = 5;
    ActiveStatus[3][0] = 0;
    ActiveStatus[3][1] = 6;
    break;
  }
}
//---------------------------------------------------------------------------
/* * * * * * * * * * * * * * * * * * * * * *
* 内部函数:初始掉落时,将根据方块的样式决定下一次将要掉下来的动态数组的值
* * * * * * * * * * * * * * * * * * * * * */
void TForm1::RectStatusToNextStatus(int m_which)
{
  switch(m_which)
  {
  case 1:
    NextStatus[0][0] = 0;
    NextStatus[0][1] = 1;
    NextStatus[1][0] = 1;
    NextStatus[1][1] = 1;
    NextStatus[2][0] = 2;
    NextStatus[2][1] = 1;
    NextStatus[3][0] = 3;
    NextStatus[3][1] = 1;
    break;
  case 2:
    NextStatus[0][0] = 0;
    NextStatus[0][1] = 1;
    NextStatus[1][0] = 1;
    NextStatus[1][1] = 1;
    NextStatus[2][0] = 0;
    NextStatus[2][1] = 2;
    NextStatus[3][0] = 1;
    NextStatus[3][1] = 2;
    break;
  case 3:
    NextStatus[0][0] = 1;
    NextStatus[0][1] = 0;
    NextStatus[1][0] = 0;
    NextStatus[1][1] = 1;
    NextStatus[2][0] = 1;
    NextStatus[2][1] = 1;
    NextStatus[3][0] = 1;
    NextStatus[3][1] = 2;
    break;
  case 4:
    NextStatus[0][0] = 0;
    NextStatus[0][1] = 1;
    NextStatus[1][0] = 1;
    NextStatus[1][1] = 1;
    NextStatus[2][0] = 1;
    NextStatus[2][1] = 2;
    NextStatus[3][0] = 2;
    NextStatus[3][1] = 2;
    break;
  case 5:
    NextStatus[0][0] = 1;
    NextStatus[0][1] = 1;
    NextStatus[1][0] = 2;
    NextStatus[1][1] = 1;
    NextStatus[2][0] = 0;
    NextStatus[2][1] = 2;
    NextStatus[3][0] = 1;
    NextStatus[3][1] = 2;
    break;
  case 6:
    NextStatus[0][0] = 0;
    NextStatus[0][1] = 1;
    NextStatus[1][0] = 0;
    NextStatus[1][1] = 2;
    NextStatus[2][0] = 1;
    NextStatus[2][1] = 2;
    NextStatus[3][0] = 2;
    NextStatus[3][1] = 2;
    break;
  case 7:
    NextStatus[0][0] = 0;
    NextStatus[0][1] = 1;
    NextStatus[1][0] = 1;
    NextStatus[1][1] = 1;
    NextStatus[2][0] = 2;
    NextStatus[2][1] = 1;
    NextStatus[3][0] = 0;
    NextStatus[3][1] = 2;
    break;
  }
}
//---------------------------------------------------------------------------
/* * * * * * * * * * * * * * * * * * * * * *
* 内部函数:当前方块下降
* * * * * * * * * * * * * * * * * * * * * */
void TForm1::RectDown()
{
  ActiveIsBottom();
  if (!m_isBottom)
  {
    //清除以前的方块
    int x1,x2,x3,x4,y1,y2,y3,y4;
    x1 = ActiveStatus[0][0];
    x2 = ActiveStatus[1][0];
    x3 = ActiveStatus[2][0];
    x4 = ActiveStatus[3][0];
    y1 = ActiveStatus[0][1];
    y2 = ActiveStatus[1][1];
    y3 = ActiveStatus[2][1];
    y4 = ActiveStatus[3][1];
    GameStatus[x1][y1]=0;
    GameStatus[x2][y2]=0;
    GameStatus[x3][y3]=0;
    GameStatus[x4][y4]=0;
    InvalidateCurrent();

    //方块下落
    ActiveStatus[0][0] += 1;
    ActiveStatus[1][0] += 1;
    ActiveStatus[2][0] += 1;
    ActiveStatus[3][0] += 1;
    GameStatus[x1+1][y1]=1;
    GameStatus[x2+1][y2]=1;
    GameStatus[x3+1][y3]=1;
    GameStatus[x4+1][y4]=1;

    InvalidateCurrent();
  }
}
//---------------------------------------------------------------------------
/* * * * * * * * * * * * * * * * * * * * * *
* 内部函数:当前方块下降加速,左移,右移
* * * * * * * * * * * * * * * * * * * * * */
void TForm1::RectArrow(int m_Type)
{
  //清除以前的方块
  int x1,x2,x3,x4,y1,y2,y3,y4;
  x1 = ActiveStatus[0][0];
  x2 = ActiveStatus[1][0];
  x3 = ActiveStatus[2][0];
  x4 = ActiveStatus[3][0];
  y1 = ActiveStatus[0][1];
  y2 = ActiveStatus[1][1];
  y3 = ActiveStatus[2][1];
  y4 = ActiveStatus[3][1];

  //如果方块已到底则不能再移动
  switch(m_Type)
  {
  case LEFT:
    if ( (ActiveStatus[0][1]>0) && LeftIsLimit() && !m_isBottom)
    {
      //清原来的方块
      GameStatus[x1][y1]=0;
      GameStatus[x2][y2]=0;
      GameStatus[x3][y3]=0;
      GameStatus[x4][y4]=0;

      InvalidateCurrent();

      ActiveStatus[0][1] -= 1;
      ActiveStatus[1][1] -= 1;
      ActiveStatus[2][1] -= 1;
      ActiveStatus[3][1] -= 1;
      GameStatus[x1][y1-1]=1;
      GameStatus[x2][y2-1]=1;
      GameStatus[x3][y3-1]=1;
      GameStatus[x4][y4-1]=1;

      InvalidateCurrent();
    }
    break;
  case RIGHT:
    if ( (ActiveStatus[3][1]< m_iCol-1) && RightIsLimit() && !m_isBottom)
    {
      //清原来的方块
      GameStatus[x1][y1]=0;
      GameStatus[x2][y2]=0;
      GameStatus[x3][y3]=0;
      GameStatus[x4][y4]=0;

      InvalidateCurrent();

      ActiveStatus[0][1] += 1;
      ActiveStatus[1][1] += 1;
      ActiveStatus[2][1] += 1;
      ActiveStatus[3][1] += 1;
      GameStatus[x1][y1+1]=1;
      GameStatus[x2][y2+1]=1;
      GameStatus[x3][y3+1]=1;
      GameStatus[x4][y4+1]=1;

      InvalidateCurrent();
    }
    break;
  case DOWN:
    //顺序下降,每降一级判断是否已到底
    RectDown();
    break;
  }

}
//---------------------------------------------------------------------------
/* * * * * * * * * * * * * * * * * * * * * *
* 内部函数:判断当前方块是否已到底
* * * * * * * * * * * * * * * * * * * * * */
void TForm1::ActiveIsBottom()
{
  //到底有两种概念:1是已到底部,2是下面碰到了另外的方块
  int x1,x2,x3,x4;
  int x,xx,yy,i;

  x1 = ActiveStatus[0][0];
  x2 = ActiveStatus[1][0];
  x3 = ActiveStatus[2][0];
  x4 = ActiveStatus[3][0];

  //已到底
  //如果下面碰到了另外的方块
  //一个方块分为四个小方块,只有这样的小方块下面有另外的方块才算到底,这样的小方块满足条件如下:
  //它的下面不再有本方块的另外的小方块
  //用算法描述为:y坐标相等的一组小方块中的最下面的哪个小方块, 我称之为接触面

  if (x1>=m_iRow-1 || x2>=m_iRow-1 || x3>=m_iRow-1 || x4>=m_iRow-1)
    m_isBottom = TRUE;
  else
  {
    for (i=0;i<4;i++)
    {
      if (InterFace[m_currentRect][i] > -1)
      {
        x=InterFace[m_currentRect][i];
        xx=ActiveStatus[x][0]+1;
        yy=ActiveStatus[x][1];
        if (GameStatus[xx][yy]==1)
          m_isBottom = TRUE;
      }
    }
  }

  BOOL m_bIsSucced;
  int k,j;
  int m_iMuch=0; //本次销掉的行数

  //计分规则:一次销掉一行,加100分,一次销掉两行,加400分,三行,900分
  //例如销掉x行,则分数为:x*(x*100)

  if (m_isBottom)
  {
    //判断是否已得分
    for (i=0;i<m_iRow;i++)
    {
      m_bIsSucced = TRUE;
      for (j=0;j<m_iCol;j++)
        if (GameStatus[i][j]==0)
          m_bIsSucced = FALSE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -