{ }
if( \
continue;
// 使用API dIsPointInSprite 判断指定坐标是否位于某个名字的精灵内部 if(m_spBlock[iLoop]->IsPointInSprite(fMouseX, fMouseY)) { }
iClickIndex break;
=
iLoop;
5、 这里我们需要用到将一维数组转换为二维数组,原理与我们前面二维数组转换为一
维数组的方面相反。只要将一维数组下标值对二维数组中每行的元素数进行求余就能得到二维数组的X下标值,将一维数组对二维数组中的每行的元素数进行求商就能得到二维数组的Y下标值。为简化操作,我们分别将这两个操作定义为函数形式直接调用。在LessonX.h中添加这两个函数的声明:
int OneIndexToX( const int iIndex ); int OneIndexToY( const int iIndex ); 在LessonX.cpp中添加这两个函数的定义:
int CGameMain::OneIndexToX( const int iIndex ) {
return (iIndex % BLOCK_COUNT); }
int CGameMain::OneIndexToY( const int iIndex ) {
return (iIndex / BLOCK_COUNT); }
6、 我们将步骤4得到的一维数组下标值转换为二维数组m_iBlockState的下标值。这样
我们就可以在m_iBlockState中查找该鼠标点击到的方块精灵周围是否有空位。在二维数组里查找鼠标点击的方块上下左右4个方向上是否有空位。注意边界判断,否则数组访问会越界。比如判断左边时,需要判断是否已经是最左边的索引(iIndexX == 0)。如果有空位(值为0),则将该空位的索引赋值给下面这2个变量iEmptyIndexX和iEmptyIndexY保存。在OnMouseClick中添加下面代码:
// 判断鼠标是否点中方块 if( -1 == iClickIndex ) return;
// 将该一维数组的Index转换成二维数组的X,Y int iIndexX = OneIndexToX( iClickIndex ); int iIndexY = OneIndexToY( iClickIndex ); int iEmptyIndexX = -1, iEmptyIndexY = -1;
// X 左方向(4个方向均需要判断是否是位于边缘,iIndexX > 0 即起此作用) if( iIndexX > 0 ) { if( 0 == m_iBlockState[iIndexY][iIndexX - 1] ) {
}
}
iEmptyIndexX = iIndexX - 1; iEmptyIndexY = iIndexY;
// X 右方向
if( -1 == iEmptyIndexX && iIndexX < BLOCK_COUNT - 1 ) { if( 0 == m_iBlockState[iIndexY][iIndexX + 1] ) { iEmptyIndexX = iIndexX + 1; iEmptyIndexY = iIndexY; } }
// Y 上方向
if( -1 == iEmptyIndexY && iIndexY > 0 ) { if( 0 == m_iBlockState[iIndexY - 1][iIndexX] ) { iEmptyIndexX = iIndexX; iEmptyIndexY = iIndexY - 1; } }
// Y 下方向
if( -1 == iEmptyIndexY && iIndexY < BLOCK_COUNT - 1 ) { if( 0 == m_iBlockState[iIndexY + 1][iIndexX] ) { iEmptyIndexX = iIndexX; iEmptyIndexY = iIndexY + 1; }
}
7、 如果找到空位,则将鼠标点击的方块精灵移动到该空位上。在二维数组里,将该索
引对应的值进行交换以及将两个方块精灵的名称交换,然后再将鼠标点击的精灵移动到新的位置上。添加下面代码:
// 判断是否找到空位
if( -1 == iEmptyIndexX || -1 == iEmptyIndexY ) return;
// 有空位,在二维数组里,将该索引对应的值进行交换
m_iBlockState[iEmptyIndexY][iEmptyIndexX] = m_iBlockState[iIndexY][iIndexX]; m_iBlockState[iIndexY][iIndexX] = 0;
// 对应的名字也进行交换 int iOneIndex = XYToOneIndex( iEmptyIndexX, iEmptyIndexY ); const char* tmpName=m_spBlock[iOneIndex]->GetName();
m_spBlock[iOneIndex]=new CSprite(m_spBlock[iClickIndex]->GetName()); m_spBlock[iClickIndex]=new CSprite(\ // 将该精灵移动到对应的位置
MoveSpriteToBlock( m_spBlock[iOneIndex], iEmptyIndexX, iEmptyIndexY );
8、 最后我们需要在Main.cpp中的OnMouseClick函数里面添加对鼠标点击消息的响应
代码:
g_GameMain.OnMouseClick(iMouseType,fMouseX,fMouseY); 至此,本实验结束。
实验五 判断游戏是否胜利
【实验内容】
步骤一、循环遍历判断是否胜利 步骤二、重新开始游戏 【实验思路】
判断游戏是否胜利主要是看所有方块的排列顺序是否为1至15,并且第16个位置的值为0。判断是否胜利的函数需要程序每次调用主函数的时候检测一次。 【实验指导】
1、 进入LessonX.h中添加我们自定义的判断是否胜利的函数IsGameWin的声明:
int IsGameWin();
2、 进入LessonX.cpp中添加该函数的定义,在文件的最后添加如下代码:
int CGameMain::IsGameWin() { }
3、 判断游戏是否胜利的算法主要是:使用2个for循环遍历二维数组m_iBlockState,
当数组里边的值为如下排列的时候,游戏胜利:第一个值是 1,第二个是 2,... 第15个是15。注意第16个(二维数组的最后一个)是空位,不用判断第16个(或者判断第16个的值为0)游戏胜利返回1,否则返回0. 如果在循环判断前15个的时候,只要其中一个值不符,不需要再往下执行,直接返回0即可。
在上面的函数定义里面添加如下的变量声明:
int iLoopX
int iResult
= 0, iLoopY = 0; = 1;
利用两个for循环遍历m_iBlockState里面的数值,如果循环到数组的最后一个,说明该数组所有值符合游戏胜利的条件,则跳出循环,函数返回成功。如果有一个值不符合,则代表游戏没有胜利。实现代码如下:
{
for( iLoopX = 0; iLoopX < BLOCK_COUNT; iLoopX++ ) {
// 数组的最后一个
if( BLOCK_COUNT - 1 == iLoopX && BLOCK_COUNT - 1 == iLoopY ) for( iLoopY = 0; iLoopY < BLOCK_COUNT; iLoopY++ )
}
}
break;
// 其中一个值不等于,那么就没有胜利 if( m_iBlockState[iLoopY][iLoopX] != iResult )
return 0;
iResult++;
return 1;
4、 判断游戏是否胜利的函数以及完成。但是系统需要定时检测当前游戏是否是胜利的
状态,因此需要在主循环里面添加这个函数的if判断,如果游戏没有胜利,则执行GameRun函数,如果胜利,则执行GameEnd函数。因此在GameMainLoop将GameRun函数的if(true)改为if(!IsGameWin())。 5、 如果游戏成功需要执行GameEnd函数,重新开始游戏。进入GameEnd函数,添加下面一行:
// 显示提示开始文字
m_spGameBegin->SetSpriteVisible(1); 至此,本实验结束。
相关推荐: