连连看游戏的设计与实现.docx

上传人:b****7 文档编号:25509771 上传时间:2023-06-09 格式:DOCX 页数:62 大小:363.09KB
下载 相关 举报
连连看游戏的设计与实现.docx_第1页
第1页 / 共62页
连连看游戏的设计与实现.docx_第2页
第2页 / 共62页
连连看游戏的设计与实现.docx_第3页
第3页 / 共62页
连连看游戏的设计与实现.docx_第4页
第4页 / 共62页
连连看游戏的设计与实现.docx_第5页
第5页 / 共62页
点击查看更多>>
下载资源
资源描述

连连看游戏的设计与实现.docx

《连连看游戏的设计与实现.docx》由会员分享,可在线阅读,更多相关《连连看游戏的设计与实现.docx(62页珍藏版)》请在冰豆网上搜索。

连连看游戏的设计与实现.docx

连连看游戏的设计与实现

苏州高博软件技术职业学院

学生毕业设计(论文)报告

 

系别计算机科学技术

专业计算机应用

班级1310计应YZ

姓名支峰

学号013321018

设计(论文)题目连连看游戏的设计与实现

指导教师贺雪梅

起迄日期2015年10月16日-2016年4月25日

 

 

连连看游戏的设计与实现

摘要本文用VisualC++来设计与实现简单的连连看游戏的基本功能,玩家可以在游戏区域中通过键盘控制来选取相同的两个物件,采用特定的消除规则对它们进行消除的操作,当游戏区域中的所有方块对都被消除后玩家即可胜利.本次课程设计对该游戏的算法以及游戏图案的绘制进行详细的介绍.运用连线相消的方法完成了连连看游戏。

关键词:

VisualC++6。

0;连连看;游戏;3D绘图

1引言

1.1连连看游戏介绍

游戏“连连看”顾名思义就是找出相关联的东西,它来源于街机游戏《四川麻将》和《中国龙》,是给一堆图案中的相同图案进行配对的简单游戏,在2003年,一个叫做朱俊的网友将这种形式搬到了PC上,立刻成为办公一族的新宠,并迅速传遍了世界各地。

饱受工作压力的人们没有太多的时间进行复杂的游戏,而对于这种动动鼠标就能过关的游戏情有独钟.之后村子的连连看风靡版,阿达的连连看奥运版,连连看反恐版,还有敏敏连连看,水晶连连看等遍地开花,造就了一个连连看的新世界。

连连看游戏有多种地图样式和道具系统、大大加强了游戏的可玩性,是一款老少皆宜的休闲佳品.

1。

2课程设计的目的

网络小游戏制作的目的是满足了人们休闲的需要,在紧张工作之余休闲类的小游戏能够给人带来最大程度的放松,也可以增进人们之间的交流,沟通,通过游戏还可以认识更多的朋友,也可以到达跨省、跨市,甚至跨国间人们互相娱乐的目的。

另外也想通过本次课程设计将三年来所学的专业知识和其他方面的知识融入到实际应用中。

1.3主要问题

开始制作游戏时,主要要解决的问题有以下几个方面:

如何设置整个游戏的界面;如何控制连连看游戏中随机图片的生成且每种图片必须为偶数个;游戏开始后,判断鼠标两次点击的图片能否消去,即图片是否相同且图片之间路径的判断.

1.4课题实现技术的简要说明

VisualC++是一个功能强大的可视化软件开发工具,VisualC++6.0不仅是一个C++编译器,而且是一个基于Windows操作系统的可视化集成开发环境(integrateddevelopmentenvironment,IDE).VisualC++6。

0由许多组件组成,包括编辑器、调试器以及程序向导AppWizard、类向导ClassWizard等开发工具。

这些组件通过一个名为DeveloperStudio的组件集成为和谐的开发环境。

VisualC++一直被认为是目前最好的软件开发工具之一,其在界面开发、执行速度、代码的移植性方面都有很强的优势.所以,实现本系统,VC++是一个相对较好的选择。

2系统需求分析

整个游戏程序包括了进入记录,图片消去和过关结果三个阶段,在处理鼠标响应事件中伴随着3D绘图.程序通过调试运行,实现了设计目标,能够满足连连看游戏玩家的需要。

2。

1可行性分析

(1)技术可行性分析

技术上的可行性分析主要分析现有技术条件能否顺利完成开发工作,硬件、软件配置能否满足开发者的需要,各类技术人员的数量,水平,来源等。

连连看系统的工作主要是在开发者和玩家之间架起一座桥梁,能相互沟通信息和处理信息。

这一特点非常适合计算机特点,通过网络Internet技术,发挥计算机的信息传输速度快、准确度高的优势。

计算机硬件和软件技术的飞速发展,为系统的建设提供了技术条件。

(2)社会可行性分析

社会可行性有时也称为操作可行性,主要论证新系统在玩家在游戏过程中的感受与反馈信息。

在当前信息技术飞速发展的大环境下,计算机技术和软件技术的更新使得游戏更加的易掌握。

2.2功能需求分析

关于连连看的功能描述如下:

运行游戏并进行初始化工作,将整个游戏区域分成纵向和横向扩展的若干个小方块,并且这些小方块是由多种动物图案成对地分布于游戏区域的不同位置。

玩家可以通过选取相同的两个物件来对它们进行消除的操作,直到将游戏区域中的所有方块对都被消除后为胜利.

2.3性能需求分析

(1)硬件环境

●处理器:

InterCR300或是更高。

●内存:

128MB(建议196MB).

●硬盘空间:

20MB。

(2)软件环境

●操作系统:

Windows98或是Windows2000/WindowsNTServer4.0。

 

3系统设计

3.1系统功能设计

连连看系统的设计流程图如图3。

1所示。

图3.1连连看游戏的设计流程图

3.2系统功能模块总设计

这个游戏的主要类是游戏模式类,类名为CLinkToLinkDlg。

这个类主要对包括图案方块的销毁判断,游戏胜利判断以及整个游戏用户交换功能的实现。

它的图如图3。

2所示。

 

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

图3。

2游戏模式类图

 

4系统详细设计与实现

4.1游戏地图设计

对于整个游戏区域,可以把它看作一个是由若干个小方块构成的地图,而且每一个小方块放置着不同的动物图案,可将其称之为图案小方块。

这些图案小方块零散地分布在地图的不同位置区域,并且每一个图案小方块都有与其对应的完全一样的另外一个小方块,如图4。

1所示。

图4。

1游戏地图设计图

如图4。

1所示,整个游戏游戏区域被抽象成一个有坐标位置属性的平面,平面上零散地分布着若干个小方块,并且这些小方块的物种起码是成对出现的。

经过前面的描述和分析后,可以把游戏区域地图用一个数组m_map来表示.m_map是把地图设计成一个动态分配的int整形一维数组,对地图中的行列数的表达,用一个转换法则即可.可以在LinkToLinkDlg类对象定义中添加地图核心数据的成员变量,具体如下:

//地图位置相关属性组

int*m_map;//动态地图数据头指针(一维数组)

intm_nRow;//地图的行数(虚拟)

intm_nCol;//地图的列数(虚拟)

上面的成员变量中定义了一个整形指针标量m_map,用于记录动态分配出来的一维数组地图空间的首地址。

对于地图区域中的某个小方块的类型,可以用一个整形的ID来进行识别。

这里为标识地图的行列位置分别添加m_nRow和m_nCol变量.

现在,地图的数据结构已经设计好。

下面对游戏进行初始化。

由于方块需要成对地出现,因此在做地图的初始化时,不仅仅是对动物种类做简单的随机取数,然后将该随机选取出来的物件放到地图区域中去就了事,而是需要成对地对物种进行成对选取,就是说地图中的小方块必须是偶数个。

前面提到过,把地图数组设置成动态分配方式,目的是让其数据空间可以根据行列数的需求动态地获取,而对于实际不同大小比例的地图可以预先定义几组关于行列数的宏来实现。

当需要创建时,根据宏值的不同分配不同大小的地图空间即可。

接下来在LinkToLinkDlg类的构造函数对地图数据进行相关的初始化:

#defineROWCOUNT8//行数

#defineCOLCOUNT12//列数

CLinkToLinkDlg:

:

CLinkToLinkDlg(CWnd*pParent/*=NULL*/)

:

CDialog(CLinkToLinkDlg:

:

IDD,pParent)

{……

//初始化行列数

m_nRow=ROWCOUNT;

m_nCol=COLCOUNT;

//根据行列数动态分配内核数据数组空间

m_map=newint[m_nRow*m_nCol];

}

CLinkToLinkDlg:

~CLinkToLinkDlg()

{

//释放动态数组空间

delete[]m_map;

在LinkToLinkDlg类对象的实现中,定义了一些关于地图行列数的宏,如ROWCOUNT和COLCOUNT,并且在LinkToLinkDlg类对象的构造函数中,进行了行列的真实确认赋值,并根据当前行列数的大小对地图数据空间进行动态创建.因为地图数据是用new在堆栈动态创建的,所以在销毁该对象时要将这些内存空间释放,如代码所示在LinkToLinkDlg类对象的析构函数中调用delete将m_map指向的所有空间都释放掉。

4。

2初始化工作

接下来,再分配好的空间中放上适当的图案方块物件,对数据进行初始化.即需要对地图空间内的数据进行成对性的随机布局,因此可以将该功能的实现封装在StartNewGame()函数里面,其代码如下:

voidCLinkToLinkDlg:

:

StartNewGame()

{

//初始化地图,将地图中所有方块区域位置置为空方块状态

for(intiNum=0;iNum〈(m_nCol*m_nRow);iNum++)

m_map[iNum]=BLANK_STATE;

}

//部下随机种子

srand(time(NULL));

//生成随机地图

//将所有匹配成对的动物物种放进一个临时的地图中

CDWordArraytmpMap;

for(inti=0;i<(m_nCol*m_nRow)/6;i++)

for(intj=0;j〈6;j++)

tmpMap.Add(i);

//每次从上面的临时地图中取走(获取后并在临时地图删除)

//一个动物放到地图的空方块上

for(i=0;i

{

//随机挑选一个位置

intnIndex=(int(rand()*0.1+rand()*0.01+rand()))%tmpMap.GetSize();

//获取该选定物件放到地图的空方块

m_map[i]=tmpMap.GetAt(nIndex);

//在临时地图除去该动物

tmpMap.RemoveAt(nIndex);

//更新显示

Invalidate(TRUE);

在游戏进行初始化的过程中,应该先对整个地图中的各个区域做必要的初始化操作,将它们的状态设置为BLANK_START空白方块状态(无动物图案方块),关于BLANK_START空白方块状态的定义,跟其他动物方块的物种定义表达类似,也是用整数ID来对它进行标识,不过不同的是,由于他代表该方块区域无图案,所以这里用-1的宏值来表示,具体定义如下:

#defineBLANK_STATE-1//空方块(没有任何动物)

可以看到,对图案方块的布局,先用srand()函数对时间函数布下随机种子,然后调用rand()函数对具体的图案方块的种类进行随机的获取。

在这里需要引入一个临时地图tmpMap,该临时地图的大小与内核数据地图的大小一致,并且先添置好4组完全一样的图案类型ID数据(0~(m_nCol*m_nRow)/4),然后再将已经安放在tmpMap中的图案作随机抽取,并放到内核地图数据中去,将取出的元素从tmpMap中除去.

4.3图案方块的连接判断

对于选中的两个方块的销毁,他们必须符合下面3个条件:

(1)选中的两个方块图案相同。

(2)选中的两个方块之间没有障碍物阻碍的情况下,可以用若干个垂直的直线线段连接起来.

(3)这些将它们连接起来的直线线段的折点不超过两个(连接线由x轴和轴的平行线组成)。

现在针对

(2)和(3)进行分析,如图4—3.

图4-2所示可知道,同种物件的连接方式大致可以分成以下3种:

(1)直接方式。

(2)有一个折点的垂直线段连接.

(3)有两个折点的垂直线段连接。

直接连接方式

在直接连接方式中,必须要求所选定的两个方块在同一水平直线上(可以为x方向或y方向),并且两个方块之间没有任何其他图案方块。

一个这点连接方式

所选定的两个方块如果通过折点的方式连接,那么对于折点来说,每个折点必定有且至少有一个坐标(x或y)是和其中一个目标点相同的,即折点必定在两个目标点所在的x方向或y方向的直线上。

此外,对于一个折点连接的情况,折点应该为第一个选中方块的横向线或纵向线与第二个选中方块的纵向线和横向线相交而得出.

两个折点的连接方式

这种方式的两个折点所连成的直线与两物件的直接连线可以构成平行线,因此可以根据这个规律,将这条水平线在游戏区域允许的条件上下移动,然后通过判断整条带垂直折线点的曲线之间有无障碍物方式来确定是否可以连同。

这种情况可以分为两种情况:

1)选中的两图案方块在同一直线,两折点间的直连线可在其这两个方块之间的空间位置作移动,其约束是不超过游戏边界区域。

2)选中的两图案方块不在同一直线,两折点间的直连线可在两个方块之间的空间位置作移动,其约束是两方块之间的区域。

经过上面详细的分析后,可以对选定的两方块是否可以作抵消操作可以这样设计下去。

首先,对简单的直接连情况进行判断,看其是否符合条件,假如不能,再加深一个级别的复杂度,对一个折点的情况进行判断,依次类推,如下图4。

2所示。

图4.2连线规则图

连线流程图如图4。

3所示。

图4。

3连线流程图

根据如图4.3所示的流程图,可以对选定的两个方块(分别在(x1,y1)以及(x2,y2)两个区域位置,其中x,y分别代表行与列的概念)是否可以抵消作以下实现.把该功能封装在IsLink()函数里面,其代码如下所示:

//判断选中的两个方块是否可以消除

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;

}

在上面的实现中,先是对直连方式中的x方向直连Y1_Link_Y2()以及y方向直连X1_Link_X2()这两种情况进行判断,如果尚未取得结果,再通过调用OneCornerLink()函数对一个折点的情况进行判断,或者更糟糕的时候调用TwoCornerLink()函数对两个这点的情况进行判断,然后得出最终结果.

下面将对上面涉及到的子功能模块进行实现,代码如下所示:

//X直接连通

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;

//

直角接口连通

BOOLCLinkToLinkDlg:

:

OneCornerLink(intx1,inty1,intx2,inty2)

{

if(x1〉x2)

{

intn=x1;

x1=x2;

x2=n;

n=y1;

y1=y2;

y2=n;

if(y2〈y1)

{

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;

}

//

直角接口连通

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〈m_nCol;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)

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 机械仪表

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1