📄 unit1.cpp
字号:
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 + -