|
/生成新的方块
currentRockIndex = nextRockIndex ;
nextRockIndex = rand()%g_rockTypeNum ;
currentRockLocation.left = initRockLocation.left ;
currentRockLocation.top = initRockLocation.top ;
}
//显示预览
DrawRock(nextRockIndex, &previewLocation, TRUE) ;
//如果超时(且能下落),自动下落一格
// 这个超时时间400-80*g_grade 是本人根据实验自己得出的
// 一个速度比较适中的一个公式(g_grade不会大于等于5)
DWORD newtime = GetTickCount();
if (newtime - oldtime >= (unsigned int)(400-80*g_grade) && moveAbled == TRUE)
{
oldtime = newtime ;
DrawRock(currentRockIndex, ¤tRockLocation, FALSE) ; //擦除原先位置
currentRockLocation.top += ROCK_SQUARE_WIDTH ; //下落一格
}
//根据当前游戏板的状况判断是否满行,并进行满行处理
ProcessFullRow() ;
//判断是否游戏结束
if (isGameOver())
{
MessageBox( NULL,游戏结束, GAME OVER, MB_OK ) ;
exit(0) ;
}
//测试键盘是否被敲击
if (kbhit())
{
userHitChar = getch() ;
ProccessUserHit(userHitChar, ¤tRockIndex, ¤tRockLocation) ;
}
Sleep(20) ; //降低CPU使用率
}//结束外层while(1)
}
/*******************************************************************************
* Function Name : ProccessUserHit
* Description : 处理用户敲击键盘
* Be called : PlayGame()
* Input : userHitChar 用户敲击键盘的ASCII码
rockIndexPtr 当前俄罗斯方块在rockArray中的下标
rockLocationPtr 当前方块在游戏界面中的位置
* Output : rockIndexPtr 响应用户敲击后 新方块的下标
rockLocationPtr 响应用户敲击后 新方块的位置
* Return : None
*******************************************************************************/
void
ProccessUserHit(int userHitChar, int* rockIndexPtr, struct LOCATE* rockLocationPtr)
{
switch (userHitChar)
{
case 'w' : case 'W' : //“上”键
//检查是否能改变方块形状
if (MoveAble(rockArray[*rockIndexPtr].nextRockIndex, rockLocationPtr, DIRECT_UP))
{
DrawRock(*rockIndexPtr, rockLocationPtr, FALSE) ;
*rockIndexPtr = rockArray[*rockIndexPtr].nextRockIndex ;
}
break ;
case 's' : case 'S' : //“下”键
DrawRock(*rockIndexPtr, rockLocationPtr, FALSE) ; //擦除原先位置
rockLocationPtr->top += ROCK_SQUARE_WIDTH ;
break ;
case 'a' : case 'A' : //“左”键
if (MoveAble(*rockIndexPtr, rockLocationPtr, DIRECT_LEFT))
{
DrawRock(*rockIndexPtr, rockLocationPtr, FALSE) ;
rockLocationPtr->left -= ROCK_SQUARE_WIDTH ;
}
break ;
case 'd' : case 'D' : //“右”键
if (MoveAble(*rockIndexPtr, rockLocationPtr, DIRECT_RIGHT))
{
DrawRock(*rockIndexPtr, rockLocationPtr, FALSE) ;
rockLocationPtr->left += ROCK_SQUARE_WIDTH ;
}
break ;
case ' ' : //空格(快速下落)
DrawRock(*rockIndexPtr, rockLocationPtr, FALSE) ;
FastFall(*rockIndexPtr, rockLocationPtr, rockLocationPtr) ;
break ;
case 13 : //回车键(暂停)
while(1)
{ userHitChar = getch() ;
if (userHitChar==13)
break ;
}
break ;
default :
break ;
}
}
/*******************************************************************************
* Function Name : MoveAble
* Description : 判断编号为rockIndex 在位置currentLocatePtr的方块
能否向direction移动
* Be called :
* Input : None
* Output : None
* Return : TRUE 可以移动
FALSE 不可以移动
*******************************************************************************/
BOOL
MoveAble(int rockIndex, const struct LOCATE* currentLocatePtr, int f_direction)
{
int i ;
int mask ;
int rockX ;
int rockY ;
rockX = currentLocatePtr->left ;
rockY = currentLocatePtr->top ;
mask = (unsigned int)1 << 15 ;
for (i=1; i<=16; i++)
{
//与掩码相与为1的 即为方块上的点
if ((rockArray[rockIndex].rockShapeBits & mask) != 0)
{
//判断能否移动(即扫描即将移动的位置 是否与设置的围墙有重叠)
//若是向上(即翻滚变形)
if( f_direction == DIRECT_UP )
{
//因为此情况下传入的是下一个方块的形状,故我们直接判断此方块的位置是否已经被占
if (g_gameBoard[(rockY-GUI_WALL_SQUARE_WIDTH)/ROCK_SQUARE_WIDTH+1]
[(rockX-GUI_WALL_SQUARE_WIDTH)/ROCK_SQUARE_WIDTH+1] == 1)
return FALSE ;
}
//如果是向下方向移动
else if( f_direction == DIRECT_DOWN )
{
if (g_gameBoard[(rockY-GUI_WALL_SQUARE_WIDTH)/ROCK_SQUARE_WIDTH+2]
[(rockX-GUI_WALL_SQUARE_WIDTH)/ROCK_SQUARE_WIDTH+1] ==1)
return FALSE ;
}
else //如果是左右方向移动
{ //f_direction的DIRECT_LEFT为-1,DIRECT_RIGHT为1,故直接加f_direction即可判断。
if (g_gameBoard[(rockY-GUI_WALL_SQUARE_WIDTH)/ROCK_SQUARE_WIDTH+1]
[(rockX-GUI_WALL_SQUARE_WIDTH)/ROCK_SQUARE_WIDTH+1+f_direction] ==1)
return FALSE ;
}
}
//每4次 换行 转到下一行继续
i%4 == 0 (rockY += ROCK_SQUARE_WIDTH, rockX = currentLocatePtr->left)
: rockX += ROCK_SQUARE_WIDTH ;
mask >>= 1 ;
}
return TRUE ;
}
/*******************************************************************************
* Function Name : SetOccupyFlag
* Description : 更新游戏板状态(把一些位置设置为已占用)
* Be |