called :
* Input : rockIndex 方块的下标(定位了方块的形状)
currentLocatePtr 方块的位置(用来设定已占用标识)
* Output : None
* Return : None
*******************************************************************************/
void
SetOccupyFlag(int rockIndex, const struct LOCATE * currentLocatePtr)
{
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)
{
g_gameBoard[(rockY-GUI_WALL_SQUARE_WIDTH)/ROCK_SQUARE_WIDTH+1]
[(rockX-GUI_WALL_SQUARE_WIDTH)/ROCK_SQUARE_WIDTH+1] = 1 ;
}
//每4次 换行 转到下一行继续画
i%4 == 0 (rockY += ROCK_SQUARE_WIDTH, rockX = currentLocatePtr->left)
: rockX += ROCK_SQUARE_WIDTH ;
mask >>= 1 ;
}
}
/*******************************************************************************
* Function Name : ProcessFullRow
* Description : 检查是否有满行,若有,则删除满行(并更新得分信息)
* Be called :
* Input : g_gameBoard
* Output : None
* Return : None
*******************************************************************************/
void
ProcessFullRow(void)
{
int i = 1 ;
int cnt = 0 ;
BOOL rowFulled = TRUE ;
int rowIdx = Y_ROCK_SQUARE_NUM ; //从最后一行开始往上检查
while (cnt != X_ROCK_SQUARE_NUM) //直到遇到是空行的为止
{
rowFulled = TRUE ;
cnt = 0 ;
//判断是否有满行 并消除满行
for (i = 1; i <= X_ROCK_SQUARE_NUM; i++)
{
if( g_gameBoard[rowIdx][i] == 0 )
{
rowFulled = FALSE ;
cnt++ ;
}
}
if (rowFulled) //有满行 (并更新得分信息)
{
DelFullRow(rowIdx) ;
//更新得分信息
UpdataScore() ;
rowIdx++ ;
}
rowIdx-- ;
}
}
/*******************************************************************************
* Function Name : DelFullRow
* Description : 删除游戏板的第rowIdx行
* Be called :
* Input : g_gameBoard
rowIdx 要删除的行 在g_gameBoard中的下标
* Output : None
* Return : None
*******************************************************************************/
void
DelFullRow(int rowIdx)
{
int cnt = 0 ;
int i ;
//把此行擦除
setcolor(BLACK) ;
for (i=1; i<=X_ROCK_SQUARE_NUM; i++)
{
rectangle(GUI_WALL_SQUARE_WIDTH+ROCK_SQUARE_WIDTH*i-ROCK_SQUARE_WIDTH+2,
GUI_WALL_SQUARE_WIDTH+ROCK_SQUARE_WIDTH*rowIdx-ROCK_SQUARE_WIDTH+2,
GUI_WALL_SQUARE_WIDTH+ROCK_SQUARE_WIDTH*i-2,
GUI_WALL_SQUARE_WIDTH+ROCK_SQUARE_WIDTH*rowIdx-2) ;
}
//把此行之上的游戏板方块全向下移动一个单位
while (cnt != X_ROCK_SQUARE_NUM) //直到遇到是空行的为止
{
cnt =0 ;
for (i=1; i<=X_ROCK_SQUARE_NUM; i++)
{
g_gameBoard[rowIdx][i] = g_gameBoard[rowIdx-1][i] ;
//擦除上面的一行
setcolor(BLACK) ;
rectangle( GUI_WALL_SQUARE_WIDTH+ROCK_SQUARE_WIDTH*i-ROCK_SQUARE_WIDTH+2,
GUI_WALL_SQUARE_WIDTH+ROCK_SQUARE_WIDTH*(rowIdx-1)-ROCK_SQUARE_WIDTH+2,
GUI_WALL_SQUARE_WIDTH+ROCK_SQUARE_WIDTH*i-2,
GUI_WALL_SQUARE_WIDTH+ROCK_SQUARE_WIDTH*(rowIdx-1)-2 ) ;
//显示下面的一行
if (g_gameBoard[rowIdx][i] ==1)
{
setcolor(WHITE) ;
rectangle( GUI_WALL_SQUARE_WIDTH+ROCK_SQUARE_WIDTH*i-ROCK_SQUARE_WIDTH+2,
GUI_WALL_SQUARE_WIDTH+ROCK_SQUARE_WIDTH*rowIdx-ROCK_SQUARE_WIDTH+2,
GUI_WALL_SQUARE_WIDTH+ROCK_SQUARE_WIDTH*i-2,
GUI_WALL_SQUARE_WIDTH+ROCK_SQUARE_WIDTH*rowIdx-2 ) ;
}
if (g_gameBoard[rowIdx][i] == 0)
cnt++ ; //统计一行是不是 都是空格
}//for
rowIdx-- ;
}
}
/*******************************************************************************
* Function Name : FastFall
* Description : 让编号为rockIndex 且初始位置在currentLocatePtr的方块
快速下落到底部
* Be called :
* Input : rockIndex currentLocatePtr
* Output : endLocatePtr 下落后方块的位置
* Return : None
*******************************************************************************/
void
FastFall
(int rockIndex,
struct LOCATE * currentLocatePtr,
struct LOCATE * endLocatePtr)
{
int i ;
int mask ; //掩码,用于判断方块的形状
int rockX ; //方块的坐标(4*4方格的左上角点的x轴坐标)
int rockY ; //方块的坐标(4*4方格的左上角点的y轴坐标)
while (currentLocatePtr->top <= GUI_WALL_SQUARE_WIDTH+Y_ROCK_SQUARE_NUM*ROCK_SQUARE_WIDTH)
{
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(g_gameBoard[(rockY-GUI_WALL_SQUARE_WIDTH)/ROCK_SQUARE_WIDTH+1]
[(rockX-GUI_WALL_SQUARE_WIDTH)/ROCK_SQUARE_WIDTH+1] == 1) //遇到底部
{
endLocatePtr->top = currentLocatePtr->top-ROCK_SQUARE_WIDTH ;
return ;
}
}
//每4次 换行 转到下一行继续画
i%4 == 0 (rockY += ROCK_SQUARE_WIDTH, rockX = currentLocatePtr->left)
: rockX += ROCK_SQUARE_WIDTH ;
mask >>= 1 ;
}
currentLocatePtr->top += ROCK_SQUARE_WIDTH ;
}//while()
}
/*******************************************************************************
* Function Name : isGameOver
* Description : 判断是否游戏结束
* Be called :
* Input : None
* Output : None
* Return : TRUE 游戏结束
FALSE 游戏继续
*******************************************************************************/
BOOL
isGameOver()
{
int i ;
BOOL topLineHaveRock = FALSE ; //在界面的最高行有方块的标记
BOOL bottomLineHaveRock = FALSE ; //在界面的最低行有方块的标记
for (i=1; i<=X_ROCK_SQUARE_NUM; i++)
{
if( g_gameBoard[1][i] == 1 )
topLineHaveRock = TRUE ;
if( g_gameBoard[Y_ROCK_SQUARE_NUM][i] == 1 )
bottomLineHaveRock = TRUE ;
}
//若底层行和顶层行都有方块 则说明在所有行都有方块,游戏结束
if (topLineHaveRock && bottomLineHaveRock)
return TRUE ;
else
return FALSE ;
}
下面是配置文件rockshape.ini
@###
@###
@@##
####
@@@#
@###
####
####
@@##
#@##
#@##
####
##@#
@@@#
####
####
-----
#@##
#@##
@@##
####
@###
@@@#
####
####
@@##
@###
@###
####
@@@#
##@#
####
####
-----
@###
@@##
#@##
####
#@@#
@@##
####
####
-----
#@##
@@##
@###
####
@@##
#@@#
####
####
-----
#@##
@@@#
####
####
@###
@@##
@###
####
@@@#
#@##
####
####
#@##
@@##
#@##
####
-----
#@##
#@##
#@##
#@##
@@@@
####
####
####
-----
####
@@##
@@##
####
-----
|