连连看游戏的设计与实现.docx
- 文档编号:6930745
- 上传时间:2023-01-12
- 格式:DOCX
- 页数:23
- 大小:325.02KB
连连看游戏的设计与实现.docx
《连连看游戏的设计与实现.docx》由会员分享,可在线阅读,更多相关《连连看游戏的设计与实现.docx(23页珍藏版)》请在冰豆网上搜索。
连连看游戏的设计与实现
连连看游戏的设计与实现
学生姓名:
蔡艳芳指导老师:
邓广慧
摘要本文用VisualC++来设计与实现简单的连连看游戏的基本功能,玩家可以在游戏区域中通过键盘控制来选取相同的两个物件,采用特定的消除规则对它们进行消除的操作,当游戏区域中的所有方块对都被消除后玩家即可胜利。
本次课程设计对该游戏的算法以及游戏图案的绘制进行详细的介绍。
运用连线相消的方法完成了连连看游戏。
关键词:
VisualC++;连连看;游戏;3D绘图
1引言
连连看游戏介绍
游戏“连连看”顾名思义就是找出相关联的东西,它来源于街机游戏《四川麻将》和《中国龙》,是给一堆图案中的相同图案进行配对的简单游戏,在2003年,一个叫做朱俊的网友将这种形式搬到了PC上,立刻成为办公一族的新宠,并迅速传遍了世界各地。
饱受工作压力的人们没有太多的时间进行复杂的游戏,而对于这种动动鼠标就能过关的游戏情有独钟。
之后村子的连连看风靡版,阿达的连连看奥运版,连连看反恐版,还有敏敏连连看,水晶连连看等遍地开花,造就了一个连连看的新世界。
连连看游戏有多种地图样式和道具系统、大大加强了游戏的可玩性,是一款老少皆宜的休闲佳品。
课程设计的目的
网络小游戏制作的目的是满足了人们休闲的需要,在紧张工作之余休闲类的小游戏能够给人带来最大程度的放松,也可以增进人们之间的交流,沟通,通过游戏还可以认识更多的朋友,也可以到达跨省、跨市,甚至跨国间人们互相娱乐的目的。
另外也想通过本次课程设计将三年来所学的专业知识和其他方面的知识融入到实际应用中。
主要问题
开始制作游戏时,主要要解决的问题有以下几个方面:
如何设置整个游戏的界面;如何控制连连看游戏中随机图片的生成且每种图片必须为偶数个;游戏开始后,判断鼠标两次点击的图片能否消去,即图片是否相同且图片之间路径的判断。
课题实现技术的简要说明
VisualC++是一个功能强大的可视化软件开发工具,VisualC++不仅是一个C++编译器,而且是一个基于Windows操作系统的可视化集成开发环境(integrateddevelopmentenvironment,IDE)。
VisualC++由许多组件组成,包括编辑器、调试器以及程序向导AppWizard、类向导ClassWizard等开发工具。
这些组件通过一个名为DeveloperStudio的组件集成为和谐的开发环境。
VisualC++一直被认为是目前最好的软件开发工具之一,其在界面开发、执行速度、代码的移植性方面都有很强的优势。
所以,实现本系统,VC++是一个相对较好的选择。
2系统需求分析
整个游戏程序包括了进入记录,图片消去和过关结果三个阶段,在处理鼠标响应事件中伴随着3D绘图。
程序通过调试运行,实现了设计目标,能够满足连连看游戏玩家的需要。
可行性分析
(1)技术可行性分析
技术上的可行性分析主要分析现有技术条件能否顺利完成开发工作,硬件、软件配置能否满足开发者的需要,各类技术人员的数量,水平,来源等。
连连看系统的工作主要是在开发者和玩家之间架起一座桥梁,能相互沟通信息和处理信息。
这一特点非常适合计算机特点,通过网络Internet技术,发挥计算机的信息传输速度快、准确度高的优势。
计算机硬件和软件技术的飞速发展,为系统的建设提供了技术条件。
(2)社会可行性分析
社会可行性有时也称为操作可行性,主要论证新系统在玩家在游戏过程中的感受与反馈信息。
在当前信息技术飞速发展的大环境下,计算机技术和软件技术的更新使得游戏更加的易掌握。
功能需求分析
关于连连看的功能描述如下:
运行游戏并进行初始化工作,将整个游戏区域分成纵向和横向扩展的若干个小方块,并且这些小方块是由多种动物图案成对地分布于游戏区域的不同位置。
玩家可以通过选取相同的两个物件来对它们进行消除的操作,直到将游戏区域中的所有方块对都被消除后为胜利。
性能需求分析
(1)硬件环境
处理器:
InterCR300或是更高。
内存:
128MB(建议196MB)。
硬盘空间:
20MB。
(2)软件环境
操作系统:
Windows98或是Windows2000/WindowsNTServer。
3系统设计
系统功能设计
连连看系统的设计流程图如图所示。
游戏框架的搭建
菜单的制作
连线相消算法的设计与实现
绘图界面的设计
连连看系统
图连连看游戏的设计流程图
系统功能模块总设计
这个游戏的主要类是游戏模式类,类名为CLinkToLinkDlg。
这个类主要对包括图案方块的销毁判断,游戏胜利判断以及整个游戏用户交换功能的实现。
它的图如图所示。
CLinkToLinkDlg
m_mem3DBkDC:
CDC
m_mem3DBkBmp:
Cbitmap
m_memAnimalDC:
CDC
m_memAnimalBmp:
Cbitmap
m_MemDC:
CDC
m_memBitmap:
Cbitmap
m_map:
int
m_nRow:
int
m_nCol:
int
m_nX1:
int
m_nY1:
int
GameDraw(CDC*pDC):
void
StartNewGame():
void
IsLink(intx1,inty1,intx2,inty2):
BOOL
IsWin(void):
BOOL
X1_Link_X2(intx,inty1,inty2):
BOOL
Y1_Link_Y2(intx1,intx2,inty):
BOOL
OneCornerLink(intx1,inty1,intx2,inty2):
BOOL
TwoCornerLink(intx1,inty1,intx2,inty2):
BOOL
Ythrough(intx,inty,BOOLbAdd):
BOOL
Xthrough(intx,inty,BOOLbAdd):
BOOL
LineX(intx,inty1,inty2):
BOOL
LineY(intx1,intx2,inty):
BOOL
图游戏模式类图
4系统详细设计与实现
游戏地图设计
对于整个游戏区域,可以把它看作一个是由若干个小方块构成的地图,而且每一个小方块放置着不同的动物图案,可将其称之为图案小方块。
这些图案小方块零散地分布在地图的不同位置区域,并且每一个图案小方块都有与其对应的完全一样的另外一个小方块,如图所示。
图游戏地图设计图
如图所示,整个游戏游戏区域被抽象成一个有坐标位置属性的平面,平面上零散地分布着若干个小方块,并且这些小方块的物种起码是成对出现的。
经过前面的描述和分析后,可以把游戏区域地图用一个数组m_map来表示。
m_map是把地图设计成一个动态分配的int整形一维数组,对地图中的行列数的表达,用一个转换法则即可。
可以在LinkToLinkDlg类对象定义中添加地图核心数据的成员变量,具体如下:
直接连接方式
在直接连接方式中,必须要求所选定的两个方块在同一水平直线上(可以为x方向或y方向),并且两个方块之间没有任何其他图案方块。
一个这点连接方式
所选定的两个方块如果通过折点的方式连接,那么对于折点来说,每个折点必定有且至少有一个坐标(x或y)是和其中一个目标点相同的,即折点必定在两个目标点所在的x方向或y方向的直线上。
此外,对于一个折点连接的情况,折点应该为第一个选中方块的横向线或纵向线与第二个选中方块的纵向线和横向线相交而得出。
两个折点的连接方式
这种方式的两个折点所连成的直线与两物件的直接连线可以构成平行线,因此可以根据这个规律,将这条水平线在游戏区域允许的条件上下移动,然后通过判断整条带垂直折线点的曲线之间有无障碍物方式来确定是否可以连同。
这种情况可以分为两种情况:
1)选中的两图案方块在同一直线,两折点间的直连线可在其这两个方块之间的空间位置作移动,其约束是不超过游戏边界区域。
2)选中的两图案方块不在同一直线,两折点间的直连线可在两个方块之间的空间位置作移动,其约束是两方块之间的区域。
经过上面详细的分析后,可以对选定的两方块是否可以作抵消操作可以这样设计下去。
首先,对简单的直接连情况进行判断,看其是否符合条件,假如不能,再加深一个级别的复杂度,对一个折点的情况进行判断,依次类推,如下图所示。
图连线规则图
连线流程图如图所示。
图连线流程图
根据如图所示的流程图,可以对选定的两个方块(分别在(x1,y1)以及(x2,y2)两个区域位置,其中x,y分别代表行与列的概念)是否可以抵消作以下实现。
把该功能封装在IsLink()函数里面,其代码如下所示:
计算鼠标点击方块的的位置
intx=FRONTWIDTH+%FRONTWIDTH1:
0)-1;
inty=FRONTHEIGHT+%FRONTHEIGHT1:
0)-1;
在游戏区域内并且该区域还有该区域不是空的区域
if(x =BLANK_STATE) { 假设尚未记录第一个方块 if(m_nX1==BLANK_STATE) { 判断是否点击的方块非本身,是否点击同一种动物 if((m_nX1! =x||m_nY1! =y)&& m_map[m_nY1*m_nCol+m_nX1]==m_map[y*m_nCol+x] ) { 检测是否可以消除 if(IsLink(m_nX1,m_nY1,x,y)) { 数据清理 m_map[m_nY1*m_nCol+m_nX1]=BLANK_STATE; m_map[y*m_nCol+x]=BLANK_STATE; } } 清空记录方块的值 m_nX1=BLANK_STATE; m_nY1=BLANK_STATE; 示的描述方案,可以在内存创建两个内存位图,并对它们的图像进行载入。 在需要使用的时候,则可以从这些内存位图中直接去拷贝,并绘制到游戏区域内存位图中去,接下来添加关于绘图的成员变量,如下所示。 Theframeworkdoesthisautomatically 邓VisualC++实用教程.清华大学出版社,2004 [2]唐俊明.VisualC++编程实例与技巧.高等教育出版,2002 [3]潘锦平.软件系统开发技术.西安电子科技大学出版社,1997 [4]张海藩.软件工程导论.清华大学出版社.2008 附件 ."menuitemtosystemmenu. ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX<0xF000); CMenu*pSysMenu=GetSystemMenu(FALSE); if(pSysMenu! =NULL) { CStringstrAboutMenu; (IDS_ABOUTBOX); if(! ()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu); } } Theframeworkdoesthisautomatically ForMFCapplicationsusingthedocument/viewmodel, voidCLinkToLinkDlg: : StartNewGame() { HCURSORCLinkToLinkDlg: : OnQueryDragIcon() { return(HCURSOR)m_hIcon; } voidCLinkToLinkDlg: : OnLButtonDown(UINTnFlags,CPointpoint) { 算鼠标点击方块的的位置 intx=FRONTWIDTH+%FRONTWIDTH1: 0)-1; inty=FRONTHEIGHT+%FRONTHEIGHT1: 0)-1; 游戏区域内并且该区域还有该区域不是空的区域 if(x =BLANK_STATE) { 设尚未记录第一个方块 if(m_nX1==BLANK_STATE) { 录第一个方块的位置 m_nX1=x; m_nY1=y; 断是否点击的方块非本身,是否点击同一种动物 if((m_nX1! =x||m_nY1! =y)&& m_map[m_nY1*m_nCol+m_nX1]==m_map[y*m_nCol+x] ) { 测是否可以消除 if(IsLink(m_nX1,m_nY1,x,y)) { 据清理 m_map[m_nY1*m_nCol+m_nX1]=BLANK_STATE; m_map[y*m_nCol+x]=BLANK_STATE; } } 空记录方块的值 m_nX1=BLANK_STATE; m_nY1=BLANK_STATE; //通知重绘 Invalidate(FALSE); } } //察看是否已经胜利 if(IsWin()) { MessageBox("恭喜您胜利闯关,即将开始新局"); StartNewGame(); } } BOOLCLinkToLinkDlg: : X1_Link_X2(intx,inty1,inty2) { //保证y1的值小于y2 if(y1>y2) { //数据交换 intn=y1; y1=y2; y2=n; } //直通 for(inti=y1+1;i<=y2;i++) { if(i==y2) returnTRUE; if(m_map[i*m_nCol+x]! =BLANK_STATE) break; } //左通 if(XThrough(x-1,y1,FALSE)&&XThrough(x-1,y2,FALSE)) returnTRUE; //右通 if(XThrough(x+1,y1,TRUE)&&XThrough(x+1,y2,TRUE)) returnTRUE; returnFALSE; } // //Y直接连通 // BOOLCLinkToLinkDlg: : Y1_Link_Y2(intx1,intx2,inty) { if(x1>x2) { intx=x1; x1=x2; x2=x; } //直通 for(inti=x1+1;i<=x2;i++) { if(i==x2) returnTRUE; if(m_map[y*m_nCol+i]! =BLANK_STATE) break; } //上通 if(YThrough(x1,y-1,FALSE)&&YThrough(x2,y-1,FALSE)) returnTRUE; //下通 if(YThrough(x1,y+1,TRUE)&&YThrough(x2,y+1,TRUE)) returnTRUE; returnFALSE; } // //是否同一直线通 // BOOLCLinkToLinkDlg: : LineX(intx,inty1,inty2) { if(y1>y2) { inty=y1; y1=y2; y2=y; } for(inty=y1;y<=y2;y++) { if(m_map[y*m_nCol+x]! =BLANK_STATE) returnFALSE; if(y==y2) returnTRUE; } returnFALSE; } // //是否同一直线通 // BOOLCLinkToLinkDlg: : LineY(intx1,intx2,inty) { if(x1>x2) { intx=x1; x1=x2; x2=x; } for(intx=x1;x<=x2;x++) { if(m_map[y*m_nCol+x]! =BLANK_STATE) returnFALSE; if(x==x2) returnTRUE; } returnFALSE; } // //1直角接口连通 // BOOLCLinkToLinkDlg: : OneCornerLink(intx1,inty1,intx2,inty2) { if(x1>x2) { intn=x1; x1=x2; x2=n; n=y1; y1=y2; y2=n; } if(y2 { if(LineY(x1+1,x2,y1)&&LineX(x2,y1,y2+1)) returnTRUE; if(LineY(x2-1,x1,y2)&&LineX(x1,y2,y1-1)) returnTRUE; returnFALSE; } else { if(LineY(x1+1,x2,y1)&&LineX(x2,y1,y2-1)) returnTRUE; if(LineY(x2-1,x1,y2)&&LineX(x1,y2,y1+1)) returnTRUE; returnFALSE; } returnFALSE; } // //2直角接口连通 // BOOLCLinkToLinkDlg: : TwoCornerLink(intx1,inty1,intx2,inty2) { if(x1>x2) { intn=x1; x1=x2; x2=n; n=y1; y1=y2; y2=n; } //右通 if(XThrough(x1+1,y1,TRUE)&&XThrough(x2+1,y2,TRUE)) returnTRUE; //左通 if(XThrough(x1-1,y1,FALSE)&&XThrough(x2-1,y2,FALSE)) returnTRUE; //上通 if(YThrough(x1,y1-1,FALSE)&&YThrough(x2,y2-1,FALSE)) returnTRUE; //下通 if(YThrough(x1,y1+1,TRUE)&&YThrough(x2,y2+1,TRUE)) returnTRUE; //右 for(intx=x1+1;x { if(m_map[y1*m_nCol+x]>-1) break; if(OneCornerLink(x,y1,x2,y2)) returnTRUE; } //左 for(x=x1-1;x>-1;x--) { if(m_map[y1*m_nCol+x]! =BLANK_STATE) break; if(OneCornerLink(x,y1,x2,y2)) returnTRUE; } //上 for(inty=y1-1;y>-1;y--) { if(m_map[y*m_nCol+x1]! =BLANK_STATE) break; if(OneCornerLink(x1,y,x2,y2)) returnTRUE; } //下 for(y=y1+1;y { if(m_map[y*m_nCol+x1]! =BLANK_STATE) break; if(OneCornerLink(x1,y,x2,y2)) returnTRUE; } returnFALSE; } BOOLCLinkToLinkDlg: : XThrough(intx,inty,BOOLbAdd) { if(bAdd) { for(inti=x;i if(m_map[y*m_nCol+i]! =BLANK_STATE) returnFALSE; } else { for(inti=0;i<=x;i++) if(m_map[y*m_nCol+i]! =BLANK_STATE) returnFALSE; } returnTRUE; } BOOLCLinkToLinkDlg: : YThrough(intx,inty,BOOLbAdd) { if(bAdd) { for(inti=y;i if(m_map[i*m_nCol+x]! =BLANK_STATE) returnFALSE; } else { for(inti=0;i<=y;i++) if(m_map[i*m_nCol+x]! =BLANK_STATE) returnFALSE; } returnTRUE; } // //判断选中的两个方块是否可以消除 // BOOLCLinkToLinkDlg: : IsLink(intx1,inty1,intx2,inty2) { //X直连方式 if(x1==x2) { if(X1_Link_X2(x1,y1,y2)) returnTRUE; } //Y直连方式 elseif(y1==y2) { if(Y1_Link_Y2(x1,x2,y1)) returnTRUE; } //一个转弯直角的联通方式 if(OneCornerLink(x1,y1,x2,y2)) { returnTRUE; } //两个转弯直角的联通方式 elseif(TwoCornerLink(x1,y1,x2,y2)) { returnTRUE; } returnFALSE; } // //截获键盘消息F2(用于新游戏开始) // //检测是否已经赢得了游
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 连连 游戏 设计 实现
![提示](https://static.bdocx.com/images/bang_tan.gif)