x1-1;x>-1;x--)
{
if(m_map[y1*m_nCol+x]!=BLANK_STATE)
break;
if(OneCornerLink(x,y1,x2,y2))
return TRUE;
}
//上
for(int y=y1-1;y>-1;y--)
{
if(m_map[y*m_nCol+x1]!=BLANK_STATE)
break;
if(OneCornerLink(x1,y,x2,y2))
return TRUE;
}
//下
for(y=y1+1;y
{
if(m_map[y*m_nCol+x1]!=BLANK_STATE)
break;
if(OneCornerLink(x1,y,x2,y2))
return TRUE;
}
return FALSE;
}
BOOL CLinkToLinkDlg::XThrough(int x, int y, BOOL bAdd)
{
if(bAdd)
{
for(int i=x;i if(m_map[y*m_nCol+i]!=BLANK_STATE)
return FALSE;
}
else
{
for(int i=0;i<=x;i++)
if(m_map[y*m_nCol+i]!=BLANK_STATE)
return FALSE;
}
return TRUE;
}
BOOL CLinkToLinkDlg::YThrough(int x, int y,BOOL bAdd)
{
if(bAdd)
{
for(int i=y;i if(m_map[i*m_nCol+x]!=BLANK_STATE)
return FALSE;
}
else
{
for(int i=0;i<=y;i++)
if(m_map[i*m_nCol+x]!=BLANK_STATE)
return FALSE;
}
return TRUE;
}
这里把直接连接方式分为直通
左通右通3种情况
如4-4图所示。
下面简单介绍直通和左通两种情况(右通与左通类似)
(1)直通:
直通就是在选定的两个方块直连线中,
没有被任何方块所阻碍。
(2)左通:
左通就是选定的两个方块的直连线之间有其他方块阻碍,
但是通过它的左侧可以将它们无阻碍地连通。
直连方式中的此种情况跟前面分析的两个折点连接方式中的其中一点相当类似,
如4-5图所示。
它们之间的区别就是,左通的连接线直接在其相邻的位置连通,
从而不构成垂直折点的效果而两个折点连同方式中的其中一个类似的情况是
线的连通起码要偏移一个方块的距离来形成连通。
图4-4 连接方式图 图4-5两折通道图
同理,
有上通和下通它们的情况与左通和右通类似。
4.4 游戏胜利的判断
要判断游戏的胜利,
实现起来比较简单只需对地图中的所有区域的状态进行检测就可里了
只要检测到地图中有一个图案方块还没有被抵消
则证明游戏没有结束完成判断。
其代码如下所示:
// 检测是否已经赢得了游戏
BOOL CLinkToLinkDlg::IsWin(void)
{
//检测所有是否尚有非未被消除的方块
// (非BLANK_STATE状态)
for(int i=0;i {
if(m_map[i] != BLANK_STATE)
{return FALSE;
}
}
return TRUE;
}
游戏胜利界面如图4-6所示
图4-6 通关图
至此,
已经完成整个游戏基本的内部相关功能模块的运算
接下来实现用户的交互部分的功能。
4.5鼠标交互功能的实现
对于用户交互的实现,
这里选择鼠标交互方式。
下面简单描述一下通过鼠标交互方式实现的功能。
鼠标选取两个图案方块后,程序将自动判断所选定的两个方块是否能进行抵消操作,
能则进行抵消操作。
在游戏过程中,我们不断重复上面描述的功能,
直到游戏的胜利结束。
下面将鼠标事件处理工作归纳为如图4-7所示的流程。
图4-7 鼠标交互流程图
对于鼠标交互功能的实现,
可以通过ClassWizard对鼠标左键被按下时触发的命令消息WM_LBUTTONDOWN进行拦截
并重写该消息的处理函数OnLButtonDown()其程序清单如下所示。
void CLinkToLinkDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
//○1.计算鼠标点击方块的的位置
int x=point.x/FRONTWIDTH+(point.x%FRONTWIDTH?1:0)-1;
int y=point.y/FRONTHEIGHT+(point.y%FRONTHEIGHT?1:0)-1;
//○2.在游戏区域内并且该区域还有该区域不是空的区域
if(x {
//○3.假设尚未记录第一个方块
if(m_nX1==BLANK_STATE)
{
//○4记录第一个方块的位置
m_nX1=x;
m_nY1=y;
//获取程序框架的设备环境
CDC *pWinDC = GetDC();
//临时绘制点中的方块外框
//只绘屏幕不载入内存位图
CPen myPen;
CPen *pOldPen;
myPen.CreatePen(PS_SOLID, 4, RGB(255,0,0));
pOldPen = pWinDC->SelectObject(&myPen);
//方块外框绘制,
线条环绕绘制框架
pWinDC->MoveTo(x*FRONTWIDTH,y*FRONTHEIGHT);
pWinDC->LineTo(x*FRONTWIDTH,(y+1)*FRONTHEIGHT);
pWinDC->LineTo((x+1)*FRONTWIDTH,(y+1)*FRONTHEIGHT);
pWinDC->LineTo((x+1)*FRONTWIDTH,y*FRONTHEIGHT);
pWinDC->LineTo(x*FRONTWIDTH,y*FRONTHEIGHT);
//现场恢复
pWinDC->SelectObject(pOldPen);
}
else
{
//○5.判断是否点击的方块非本身, 是否点击同一种动物
if((m_nX1!=x||m_nY1!=y)&&
m_map[m_nY1*m_nCol+m_nX1]==m_map[y*m_nCol+x]
)
{
//○6.检测是否可以消除
if(IsLink(m_nX1,m_nY1,x,y))
{
//○7.数据清理
m_map[m_nY1*m_nCol+m_nX1]=BLANK_STATE;
m_map[y*m_nCol+x]=BLANK_STATE;
}
}
//○8.清空记录方块的值
m_nX1=BLANK_STATE;
m_nY1=BLANK_STATE;
//通知重绘
Invalidate(FALSE);
}
}
//察看是否已经胜利
if(IsWin())
{
MessageBox("恭喜您胜利闯关,即将开始新局");
StartNewGame();
}
}
按照预先设计出的鼠标事件处理流程
上面已经将它转换成具体的实现代码。
下面将按照流程的子功能模块的划分方式,
对整个功能模块的具体协调和实现过程进行简单的描述。
(1)首先,利用鼠标的当前坐标位置point对每个小单元方块的宽度FRONTWIDTH和高度FRONTHEIGHT分别取模,
获取当前鼠标落点所在的游戏区域的具体行列数(x
y)。
(2)判断出该行列数(x,y)是否符合条件。
保证运算出来的行数x和列数y的预定义区域最大的行数m_nCol和列数m_nRow内,
并且点击的区域状态不是空白方块区域BLANK_STATE
(3)对判断此次鼠标书剑的选取是否与第一个方块的选取一样
只需通过用于记录第一个被选中的方块的行列数的成员变量m_nX1是否为有效即可。
这里将m_nX1以及m_nY1来记录它所在的行、列数,
并且每次经过判断后都会将它们的状态恢复为空白无选中状态BLANK_STATE。
关于这两个用作记录第一个选中图案方块行列数的成员变量,
在对话框类中的具体定义如下所示:
intm_nX1; //鼠标选中的记录方块列数
intm_nY1; //鼠标选中的记录方块行数
(4)对于本次选中的方块为第一选中的情况
先用m_nX1和m_nY1对当前的选中方块位置做记录
然后直接在屏幕的该区域绘制图像为该方块区域添加一个红色的矩形外边框
用以提示用户当前的第1个图案方块选中所在的位置。
需要注意的是,对于标记方块的加亮边框绘制是通过GetDC()函数来获取对话框窗体(屏幕)的设备环境,
对绘制的图像数据没有作历史记录的方式来绘制的。
(5)在这一处理中,对该选定方块作一些判断,
以便更高效地处理。
判断选中的方块与前一方块是否为同一图案方块,
并且此次选择不与上一次选定的方块为同一方块
然后才跳到下一步对两个选定的方块是否可以抵消的流程中去。
(6)调用前面已经实现的答功能函数IsLink()来判断当前所选定的两个图案方块是否可以抵消。
(7)如果可以抵消,对选中的两个方块在内部核心地图对应的数据状态作适当的修改,
将它们的状态记作已经被销毁的空方块状态BLANK_STATE。
(8)完成第二个图案的选取与相关的功能操作后,
我们需要前面已经选去第1个方块位置的记录作清理工作
以便下一个新方块的选择。
(9)最后,判断此次的鼠标操作是否已经胜利结束,
如果是则给予用户提示然后重新开适新的一关。
4.6连连看新纪录的实现
首先创建两个对话框模板,
一个用作当用户胜利结束游戏并打破历史记录后弹出的签名记录对话框模板IDD_DLG_NEWRECORD
另外一个是用以显示以往最高的游戏记录的对话框模板IDD_DLG_HERO。
如图4-8和图4-9所示。
图4-8 添加新记录图
图4-9 积分记录图
4.7绘图功能的实现
在完成以上所有的交互以及内部数据关联的运算处理后,
最后要将这些数据展现到屏幕上。
(1)位图图像的准备
首先,准备好一个带有不同动物种类的位图,
以及一个3D边框效果的位图如图4-10所示。
通过资源编辑器将它们引入到项目中来,
并将他妈的I
上一篇:VC设计简单的聊天室毕业论文设计
下一篇:近三年来思想工作小结(德能勤绩廉)