收藏 分销(赏)

毕业设计-c--连连看游戏1.doc

上传人:精*** 文档编号:2185529 上传时间:2024-05-22 格式:DOC 页数:17 大小:853.50KB 下载积分:8 金币
下载 相关 举报
毕业设计-c--连连看游戏1.doc_第1页
第1页 / 共17页
毕业设计-c--连连看游戏1.doc_第2页
第2页 / 共17页


点击查看更多>>
资源描述
课 程 设 计 报 告 课程名称:面向对象程序设计C++ 设计题目:连连看游戏 专 业:计算机科学与技术 姓 名: 学 号: 指导教师:李晓虹 2016 年 1 月 7 日 I 第一章 系统需求分析 相信大多数玩过QQ游戏的人对这款游戏都不陌生。这款游戏不止操作简单,规则也不难,再加上游戏速度的控制机制得宜,让整个游戏在操作过程中充满了快乐与紧张的气氛。除了游乐当中能带给使用者快乐之外,游戏的设计内容无形中也不断训练使用者的逻辑思考能力,对于依靠高度脑力工作的现代人,都可以通过这个游戏,不时的检验一下自己,所以我们不难发现,在各种可携带的电子产品上都有这款游戏的踪影。 第二章 总体设计 本游戏主要给用户提供的是游戏的娱乐功能,所以怎么提高游戏的娱乐性成为问题的关键,那么娱乐性主要体现在那些方面呢? 1, 用户界面,具有良好的用户界面能吸引人去玩; 2, 游戏的娱乐功能,具有良好的娱乐功能是游戏具有持久魅力的基础,需要设计游戏的不同级别以充分调动用户积极性; 3, 具有友好的提示功能,满足不同游戏级别的人的不同需要,增加必要的音乐效果,使用户玩起来不觉得单调乏味。 鉴于上面分析,本次设计设置不同的游戏级别主要是缩短时间的进行速度,因为图标是随机列换的,所以通过控制产生随机数的难度显得不现实。通过菜单和快捷键的操作可以适时做出游戏的提示功能,满足提示要求,如果用户对某次产生的图标分布效果不满意可以对现在有的图表资源进行有限次的重排,以满足用户的需要。 关于算法问题,这是游戏设计的核心问题,算法的选择好坏涉及到游戏的质量,采用的产生的二维随机数索引分别和对应图标对应形成游戏界面。算法需要计算两个相同图标的连通性,计算连通性需要分别判断多次,所以算法的根本在于如何判断区域连通。 第三章 详细设计 3.1 连连看的要求 1,要连接的两点上的图形是相同的。 2,两点间存在一条没有“障碍”的并且折点不超过两个的路线。 那么分析一下可以看到,一般分为三种情况。 图例说明: 假设以一个2维数组来表示一张连连看的地图,数组中元素值为0的代表游戏界面中的空格子,值大于0的代表游戏中的各种连接对象。 情况一:要连接的两点在同一条直线上 0 0 0 0 0 0 0 2 0 0 0 2 * ------ * 0 0 0 0 0 0 情况二:经过一个折点相连(+号代表折点)。 0 0 0 0 0 0 0 2 0 0 0 + * ------ + 0 + 0 0 0 2 + ------ * (两条路都可连通) 情况三:经过两个折点相连(即数字2) 0 + 0 0 0 + 0 0 0 0 0 0 0 2 0 1 0 2 0 2 0 1 0 2 0 0 0 0 0 0 或者 0 + 0 0 0 + 由于有1这个障碍,所以需要两个折点才能连通。 3.2 任意两点能否连通 寻路算法是整个游戏的核心算法。 本算法思路如下: 1, 一条直线上两点能否相连是好判断的(一个简单的循环判断即可)。 2, 对于上面图例的情况二,折点的坐标是固定的,即折点要么是[连点1的坐标x,连点2的坐标y]要么是[连点1的坐标y,连点2的坐标x] y | | | * ------ + | + ------ * ---------------- x 所以,我们只需判断连点1到折点能否连通,连点2到折点能否连通即可 得知连点1和连点2能否连通。并且由于折点与两个连点分别是在同一条直线上,所以可以由第一步轻松判断得出结论。 3,将情况三转化为情况二,(这一步是该算法中最影响性能和需要改进的地方)。 转换如下: 0 + 0 0 0 + 0 2 0 1 0 2 0 0 0 0 0 0 (情况三) 将和其中一个连点在同一条直线上的折点当作该连点,那么情况三就转化为情况二。 0 2 0 0 0 + 0 * 0 1 0 2 (星号为原先的连点) 0 0 0 0 0 0 (转化后的情况三,最左上的折点已经被替换)现在两个连接对象2之间的情形,已经变为情况二了。 4,由上可知,寻找这个被替换的折点就成了关键。因为其坐标不固定,所以只好递归一个一个寻找。 2 0 0 0 0 + 0 * 0 + 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 2 0 0 0 * 0 + 0 0 0 0 0 1 2 * 0 2 1 0 0 0 0 2 1 2 0 0 上面三个图,+号是折点,*号就是需要被替换的折点。 假设A、B两点是同一个图形,思考下面的路线。 0 0 0 0 0 0 0 0 1 0 B 0 0 0 0 0 0 0 0 A AA 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 如果我们的算法从向右开始寻找,顺时针方向旋转,那么A点先向右移动1格到达AA的位置,这时测试AA与B是否能连通(按情况二处理),结果不能,因为折点出都有“障碍”(两个1),然后A点在移动,到达AAA处。 0 0 0 0 0 0 0 0 1 0 B 0 0 0 0 0 0 0 0 A AA AAA 1 0 0 0 0 0 0 0 0 0 0 0 0 0 在AAA处,再次与B点测试连通的时候(按情况二处理),结果是可以,所以A点可以与B点连通,路线为: + * | l ---+ 再增加一个障碍: 0 0 0 0 0 0 0 0 1 1 B 0 0 0 0 0 0 0 0 A AA AAA 1 0 0 0 0 0 0 0 0 0 0 0 0 0 这次,当寻找到AAA位置时,结果为不能连通。在向右,由于有障碍,所以向右这条路,宣告失败,递归返回到原点,换一个方向从A点向下在开始判断。 0 0 0 0 0 0 0 0 1 1 B 0 0 0 0 0 0 0 0 A 0 0 1 0 0 AA 0 0 0 0 0 AAA 0 0 0 0 (向下仍不能连通)向左最后向上。 0 0 0 0 0 0 0 0 1 1 B 0 0 AA 0 0 0 0 0 A 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 (AA点与B点符合情况二,可以连通)路线为: * | ----------- | * 最坏的情况,以11*19 的大小来计算,共需移动28次,情况2共循环不超过500次。 0 0 0 0 0 0 0 0 1 1 B 0 0 0 0 1 1 1 0 A 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3.3 地图无解提示 因为连接对象的位置是固定的(用重列道具后位置也是固定的),所以以n个字符串(字符串1维数组) 来记录这些位置信息(n==游戏中出现的物体种类数),一个字符串记录一种,格式型如:10208110507151218 第一位1,表示物体的类别,后面16位每4位一组,表示属于这个类别的一个对象的位置信息,0208 表示 数组中的坐标 Array[2][8],即星星这个类别中,有一个星星在游戏中的坐标是[2][8]。 这样,我们就在同一类别中,寻找该类别中现存的任意组合能否连通。即该类中的一个对象能否和该类别中其它对象连通。 只要找到一个,即有解。如果查找完所有的,那么就提示无解。当我们消去一对连接对象时,在相应的字符串中删除掉这两个连接对象的位置信息(对应位置字符串变为-1),比如0208变为-1-1。 3.4 连接提示功能 根据上面的位置信息数组,按类别依次即时计算该连接对象能否和该类中其它连接对象相连。比如读取数组的第一个元素,在提取这个字符串中第一个连接对象的信息,比如1-1-11105-1-11218这个字符串, 提取出11,5这个位置信息,用它来连接12,18看能否连通。 3.5 重列问题 假设我们在某局游戏中共出现了15种连接对象,每种4个,用1代表星星 2代表企鹅,那么仍定义一个字符串444444444444444 一共15个4,该字符串的每一位对应一个连接对象,比如第一位对应星星在游戏中还有多少个(4个),第二位代表企鹅在游戏中还有多少个,当我们销掉某个图片的时候,也对这个字符串对应的位置-2,而将这个字符串的每一位的数字相加,就是目前游戏剩下的图片数。 现在游戏中连接对象的位置知道(位置信息数组),数量知道(定义的字符串),根据位置随机出现一个连接对象,如果该连接对象在前面定义的字符串中仍有数值(不为0),在以另一个字符串来记录这个变化(与前面功能结构完全相同),如果新字符串上的相应数值与原字符串上的相应数值相等了,则不在出现这种类型了(重列的类型数量和以前一样),扫描完所有的位置,从而实现了重列。(新旧字符串应相等,因为只是改变某个连接对象的位置,而数量没有改变)。 第四章 系统调试 本系统在 Visual Stuidio下调试通过,调试成功后,打开debug目录下exe,开始运行连连看游戏。 1 界面:该窗口具有暂停,重置,提示,背景色为黄色。 2 游戏过程:按照连连看规则消除图片之后,分数将会增加。 3 游戏完成:游戏完成后,系统会提示是否要继续进入下一关。 第五章 结果分析 5.1 编程实现 依照编程方案编程实现代码流程如下: 1, 依据算法编写各个功能函数在CView类里面,并编写辅助功能函数,便于直接调用。 2, 把各个功能衔接起来,添加消息响应函数,重点编写LButtondown()函数的编写,因为游戏的主要消息响应来自左键,以实现游戏基本功能。 3, 添加包括音效等各种资源,丰富游戏功能。 4, 设计背景,添加并编辑成绩对话框(包括两个对话框的编辑),放入需要的控件,对其进行操作,实现成绩记入,便于后续读出。 主功能函数流程图: 产生随机序列 列出每幅图片所有的位置 初始化事件 程序控制进入游戏算法 绘制时间控制条 绘制时间进度条矩形功能 设置定时器 绘制输出游戏界面 绘制各种提示信息 5.2 游戏的实现 首先需要对连连看游戏有一个整体的认识,它是在一个背景下有若十的图片,如果连续点击相同的图片,并且可以用最多两折的线段连接,之间还没有其他障碍物,就可以消掉这一对图片.如果所有的图片都被消掉.就町取得胜利。倘若在规定的时间内没有消完所有图片.则游戏失败。游戏界面如下图所示: 为了游戏的美观.当点击每个图片时。应该有类似按钮点击的效果。要实现这一点。最简单的就是把每个图片都做成一个按钮,这可以利用MFC的CButton类。编写CLLKanButton类,使其继承于Cbutton类.使每个Button都有自己的ID号,用来存储图片类型,还应该有一个CPoint类型的成员变量,用来存储每个Button的位置信息。最后在创建时。将和ID号对应的图片贴到相应的位置上即可。 主要功能代码如下: #include "stdafx.h" #include "greatellk.h" #include "greatellkDlg.h" #include "MyButton.h" #include "HerolistDlg.h" #include "XiuxiDlg.h" #include "NameDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif int m_ilastx1; int m_ilastx2; int m_ilasty1; int m_ilasty2; // 用于应用程序“关于”菜单项的CAboutDlg 对话框 class CAboutDlg : public CDialog { public: CAboutDlg(); // 对话框数据 enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() // CgreatellkDlg 对话框 CgreatellkDlg::CgreatellkDlg(CWnd* pParent /*=NULL*/) : CDialog(CgreatellkDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CgreatellkDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_LINE, m_line); DDX_Control(pDX, IDC_TIMESTATIC, m_timestatic); DDX_Control(pDX, IDC_COUNT_STATIC, m_scorestatic); } BEGIN_MESSAGE_MAP(CgreatellkDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_BN_CLICKED(IDC_START_BTN, &CgreatellkDlg::OnBnClickedStartBtn) ON_WM_TIMER() ON_BN_CLICKED(IDC_LIST_BTN, &CgreatellkDlg::OnBnClickedListBtn) ON_BN_CLICKED(IDC_ABOUTME_BTN, &CgreatellkDlg::OnBnClickedAboutmeBtn) ON_BN_CLICKED(IDC_TISHI_BTN, &CgreatellkDlg::OnBnClickedTishiBtn) ON_BN_CLICKED(IDC_RESET_BTN, &CgreatellkDlg::OnBnClickedResetBtn) ON_WM_ERASEBKGND() ON_WM_CTLCOLOR() END_MESSAGE_MAP() 对游戏的消除凡是做简要分析,对于消图来说。主要可以分为如下2种情况: (1)直连方式 (2)有一个折点的线相连 5.2.1 直连方式 对于直连方式,判断起来比较简单,只要两图片相同,在一条直线上,并且之间没有障碍物即可。如下图所示。 为CLLKanButton类添加FindLine(CPoint pl,CPoint p2)函数。实现判断是否可直连的功能。源代码如下: BOOL CLLKanButton::FindLine(CPoint pl,CPoint p2) { CLLKanDIg。parent=(CLLKanDIg。)GetParent0; int max,min; int i: ifI{p1.X)==(p2.X)) { max=(p1.y>p2.y)?p1.y:p2.y: rain=(p1.y<p2.y)?p1.y:p2.y: if(max==min+l 1 return TRUE; //相邻的两个格子 for(i=min+l:i<max;i++) { if(parent一>map[p1.x][i1 1=0) return FALSE; } return TRUE: } if{(p1.Y)==Ip2.Y)) { max={p1.x>p2.x)?p1.x:p2.x: min=Ipl.x<p2.x)?p1.x:p2.x: if(max==min+l 1 return TRUE; //相邻的两个格子 for(i=min+l:i<max;i++) { if(parent->map[i][pl_y]!=O) return FALSE; ) return TRUE; } return FALS E; } 其中,pl,p2分别保存有先后两次点击图片的位置信息。为了能够得到这些信息,可以先在CLLKanButton类中为鼠标左键按下添加消息响应。由于每个图片都是一个BuRon,因此在鼠标点击这个Button时,都会有一个this指针指向这个Button,可以利用这个this指针,将Button的类型信息、位置信息都分别保存下来。只当先后点击的是同一种图片时。才调用FindLine等函数来判断是否能消掉。这样来提高程序的运行效率。函数是这样运行的.首先要分为横向连接和纵向连接两种类型分别判断。以横向为例,谁的横坐标值小,谁就在左边,由此得到它们大致的位置信息。然后从左至右,依次判断它们之间是否有其他的图片,如果有,则返回FALSE;如果没有,则表示可以通过直连的方式,消掉这一对图片。 5.2.2其他方式 也就是有一个折点的线相连的方式,于这种方式。判断起来也相对简单.连接它们的折线的折点。其横纵坐标一定分别和它们的横纵坐标相同。如下图所示。 为CLLKanButton类添加FindOneConner(CPoint pl,CPoint p2)函数。实现判断是否可通过一个折点相连的功能。 源代码如下: BOOL CLLKanButton::FindOneConner(CPoint pl,CPoint p2) { CLLKanDIg*parent=(CLLKanDIg*)GetParent0; int maxx,maxy,minx,miny; maxx=(p1.x>p2.x)?p1.x:p2.x: maxy=(p1.y>p2.y)?p1.y:p2.y: minx=(p1.x<p2.x)?p1.x:p2.x: miny=(p1.y<p2.y)?p1.y:p2.y: //分别进行判断 if(parent一>map[minx][maxy]==0) { m—ptCrossl.x=minx; m_ptCrossl.Y=maxy; if((FindLine I pl,m_ptCrossl))&&(FindLine(m—ptCrossl,p2))) return TRUE: } if(parent一>map[maxx][miny]==0l { m—ptCrossl.X=maxx; m—ptCrossl.Y=miny; if((FindLine(pl,m—ptCrossl))&&(FindLine Im_ptCrossl,p2))) return TRUE; ) if(parent一>map[minx][miny]==0) { m—ptCrossl.X=minx; m—ptCrossl.Y=miny; if((FindLine(pl*m_ptCrossl))&&(FindLine (m_ptCrossl,p2})) return TRUE; } if(parent一>map[maxx][maxy]==0) { m_ptCrossl.x=maxx; m_ptCrossl.y=maxV: if I(FindLine(pl,m—ptCrossl))&&(FindLine (m_ptCrossl,p2))) return TRUE; } return FALSE; } 折点的横纵坐标一定分别为其中一个图片的横坐标以及另外一个点的纵坐标。由此.就可以定为出折点的位置,值得注意的是,这里可以利用已经写好的FindLine函数,来简化判断过程。 总结 本次毕业设计不仅让我独立完成了项目开发,使自身的专业技能得到很大程度的提升,还让我涉足到许多新的知识领域,拓宽了知识面,为今后的实际工作打下了坚实的基础。从中学习到的内容,将让我终身受益。以下是我这几个月工作的几点总结: 1.毕业设中计技术运用不够成熟。这次毕业设计是用Visual Studio 2005,C++语言实现的,由于未曾学习这门课程,对于C++的掌握不够全面,尤其是在控件以及类库中方法的了解不够,不仅使得程序界面不够美观,一开始也拖延了进度。 2.在实现软件时,不可避免的遇到了一些问题,存在一些不足之处。这些不足之处产生的原因主要还是对实际应用中的需求考虑不够充分,设计阶段做得不够仔细。这是在今后的工作中值得吸取的经验教训。 3. 经过本文的撰写,对连连看的基本实现有了较为全面的认识。文章中分析了设计的现状及发展,实现了基于连连看游戏的初步实现,但只涉及到人工智能的点点皮毛,而且在功能方面还不够完美。 正是此次毕业设计,我才真正从一个纯软件工程的学生走入程序开发的大门,我开始发现其实软件开发并不是纯数学——正相反,数学只占了很小的一部分。它其实是一种哲学,一种有着数学美感的哲学。 16
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 学术论文 > 毕业论文/毕业设计

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服