VC++实现连连看游戏_第1页
VC++实现连连看游戏_第2页
VC++实现连连看游戏_第3页
VC++实现连连看游戏_第4页
VC++实现连连看游戏_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、VC实现连连看游戏实用第一智慧密集一一.一一.iVc+实现连连看游戏袁伟摘要:用Vc+实现连连看游戏,可自由设置游戏时间及难度,加入秘籍功能,并自动消除图片.关键词:VC+;MFC;连连看相信大家都对QQ游戏中的连连看不陌生,那漂亮的图片以及紧张的节奏,使很多人都爱不释手.本文利用VC+,借助MFC实现一个简单的连连看游戏.1基本思路首先需要对连连看游戏有一个整体的认识,它是在一个背景下有若干的图片,如果连续点击相同的图片.并且可以用最多两折的线段连接.之间还没有其他障碍物.就可以消掉这一对图片,如果所有的图片都被消掉,就可取得胜利.倘若在规定的时间内没有消完所有图片,则游戏失败.游戏界面如图

2、1所示图1这其中需要注意几个问题.首先,必须是随机生成的,也就是说每次游戏生成的画面都不能一样.其次,每个小图片都应该是成对出现的.否则无法将它们都消掉,游戏也就无法完成了.最后,程序应该有重新排序的功能,在玩家找不到可消.一_一的图片,或者程序判断无可消的图片时,可以重新排序,以便游戏可以继续进行.为了游戏的美观,当点击每个图片时,应该有类似按钮点击的效果.要实现这一点,最简单的就是把每个图片都做成一个按钮.这可以利用MFC的CButton类.编写CLLKanButton类,使其继承于Cbutton类.使每个Button都有自己的ID号,用来存储图片类型.还应该有一个CP0int类型的成员变

3、量.用来存储每个Button的位置信息,最后在创建时.将和ID号对应的图片贴到相应的位置上即可.通过这样的思路来保证每种图片都是成对出现的:首先定位到第一个按钮的位置,随机选择一种图片,生成这个按钮,然后随机选择一个位置.仍然放置这种图片,再定位到第二个按钮的位置,随机选择一种图片,生成这个按钮,然后再随机选择一个位置.如果这个位置已经有按钮了.则重新随机选择一个位置.直到选到一个空的位置,放置相同的图片,以此类推,将整个地图布完.将地罔布完后就是游戏的过程了.根据大家熟悉的连连看规则.两个相同的图片如果可以用不超过3根的折线将其相连,就可以消掉这一对图片.关于具体算法的实现,在后面游戏核心实

4、现一章中做详细讲解.2游戏初始化以及地图生成编程环境是MicrosoftVisua1C+6.0.首先新建一个工程,选择MFCAppWizard,取名LLKan,建立一个基于对话框的工程.可以根据需要选择共享DLL模式或静态DLL模式,这里直接点击完成,如图2所示.现在程中已经有了3个类:CLLKanApp类,CLLKanDlg【3】J2ME3D手机游戏开发详解.人民邮电出版社,2007.【4J2ME手机游戏开发详解.清华大学出版丰十,2005.【5J2ME程序设计.清华大学版社,2001.3.6】Java/PDA程序设计入门.电子丁业出版社出版,20047Java2实用教程.清华大学出版社.2

5、010.1电奠翟技巧与簟8】3DMAX8入门与提高.电子工业出版社.9】火星人3DMAX8.人民邮电出版社.【10】PhotoshopCS中文版.电子T业出版社出版,2005f收稿日期:200909-25).B啊EPROGRAM图2类以及CaboutDlg类,rlJ的CIIKanDlg类就是主对话框类,可以在此类I1做一基本的设定:首先利用SetWindowPos0函数来设嚣框架的大小硬基本槿性.存CLLKanDIg类中的OnlnitDialog0函数中.在如下化置添加代码:CDlalOg:OnlnitDiaOg【】:SetWindowPos(NULL,1O0,100.750,500,SWPD

6、RAWFRAMEISWPSHOWWINDOWSWPNOZORDER);/AddAboutmenuiterntosystemmenuIDM_ABOUTBOXmustbeinthesystemcommand/range为了.示剩余时,创建个形区域CRgnnltimeRgn,在这个域内示剩余时.利用InvalidateRgn0函数刷新这一域,达到实时示Ht问的目的在CLLKanDIg类的OnPaint0丽数rl1,将原代码注释掉,添加如下代码:CPaintDCdc(this):CPenpRedPen=newCPenI:pRedPen一>CreatePen(PSSOLID,2.RGB(255,0

7、.O):/,设置字体颜色CGdiObjectpOIdPen=dc.SeIectObject(pRedPen):选择画笔CFontfont;CStringstr;strFormat(剩余时间:%d秒,mtime);/mtime中存储剩余时间信息font.CreatePointFont(10O,宋体):设置字体dc.SelectObject(&font);dc.SetTextColor(RGB(255,0O):dc.SetBkColor(TRANSPARENT):设置背景为透明dc.TextOut(1O,40,str);/显示时间其r1.第?部分代码没置字体颤色为红色.第二部分显示剩余时间

8、,1111一time存储时间信息,在cLLKanApp类的lnitlnstan?P0蛹数l,添加如下代码,将背景色设置为黑色:SetDiaIogBkColor(RGB(0,OO,RGB(255,0,O):设置背景色为黑色现存来生成游戏地罔先为CIIKanDlg类添加如下成员变量:intmjVpeNum;/图片种类数intmapMAXXMAXY;/地图数组,存储图片类型CPtrArraymbtnGroup;#Button组CLineStaticmline;用于画线其中MAXX和MAXY做如下定义#defineMAXX9|数#defineMAXY14/列数这里需要注意点.MAXXlf1lMAXY的

9、积一定要是个偶数.因为如果为奇数,IflJ不能成埘的容纳所f】的片:然后存CLLKanDlg炎llf添加1函数lnitMap(intmap【】【MAXY),源代码下:voidCLLKanDIg:InitMap(intmapiMAXY)(int1,I:intx,V:Inttype;/随机数种子srand(unsignedint)time(NULL);for(i=0;i<MAX:j+)ffor(j=0;j<MAXY;j+)(mapiljl=0;)初始化,全部置零for(i=1:i<MAXX一1:i+)for(j=1;j<MAXY一1;j+)if(mapij】!=0)cont

10、inue;elsetype=rand0%m_typeNum;/l片种类map【i儿jl=type+1:do(X=rand()%(MAXX一2)+1:Y=rand0%(MAXY一2)+1:)while(mapxy);map【xlIy】=type+1:-一疆20秭10.丽1_ll79实用第一智慧密集)鬲数首先将map数组中的数全部置零.为了将来消图时画线方便,地图最外面一圈为空,即使不放置图片,但占据一个图片的位置.然后根据前面所叙述的思想,生成整个图片数组.通过这样的过程,可以保证每种图片都是成对出现的,并且由于随机的过程,每种图片的数量也是不一样的.当图片类型比较少时,可能会有些图片多,有些图

11、片少;当图片类型较多时,基本上每种图片只出现一对或两对,增加游戏的可玩性.完成了图片数组的初始化工作后.就要显示这些图片.为此CLLKanDlg类编写函数ShowMap(intmap】【MAXY),源代码如下:voidCLLKanDIg:ShowMap(intmapMAXY)inti,j:CPointp:CStringstr;,/清除原有按钮for(i=0;i<mbtnGroup.GetSize0;i+)delete(CLLKanButton)mbtnGroup.GetAt(i);mbtnGroup.RemoveAll0;/添加新按钮for(i=1:i<=MAXX一2:i+)for

12、(j=1j<=MAXY-2;j+)p.x=i:P.Y=j:mbtnGroup.Add(newCLLKanButton(mapij,p):),/显示按钮for(i=0;i<(MAXX一2)(MAXY一2):l+)CLLKanButtonbtn=(CLLKanButton)mbtnGroupGetAt_)=btn一>Create(str,WSCHILDIBSB丌.MAP,CRect(130+(i%(MAXY一2)40.70+(i/(MAXY一2)40,17O+(i%(MAXY一2)40.110+(i/(MAXY一2)40),thisIDCBLOCK+i):if(btn一>m

13、id)/D果为O则不显示str.Format(res%d.bmp,btn一>m_d)HBITMAPmfkBmp=(HBITMAP):Loadlmage(AfxGetInstanceHandIe(),str,IMAGEBITMAP,0,0,LRCREATEDBSECTIONILRLOADFROMFILE):/加载图片.f(mfkBmp=NULL)2010.1电奠程技巧与IIif(MessageBox(.缺少图片资源!.,错误.,MBICONERRORIMBOK)=IDOK)(CDialog:OnCancel0;return;btn->SetBitmap(mfkBmp);btn一>

14、;ShowWindow(SVv-SHOW):)elsebtn一>ShowWindow(SHIDE);)函数首先清除原按钮.这是必须的.如果不做这一步,当玩完一次游戏再重新开始时.由于没有清除原按钮.就会出现错误.然后添加新按钮,用new的方法将新按钮一个一个地贴到地图中.选用的图片是QQ头像,共105张,都存放在工程目录下的res文件夹中.如果读取图片失败,则会弹出警告对话框.通过设置m_typeNum的值来调整游戏难度,图片类型越多则越难.至此,已经完成了整个游戏的初始化的_T作,在菜单栏中加入游戏开始菜单.来调用InitMap0函数和ShowMap0函数.就可以看到游戏基本的样子了.

15、当然,还可以加入定时器,来控制游戏的进程,如果设定的时间结束还没有消掉所有的图片,游戏就失败了.此外还可以在菜单栏中加入设定游戏时间和图片种类的功能,使得游戏有更高的可玩性.关于这些,这里不再做详细介绍.3游戏核心实现可以做简要分析,对于消图来说,可以分为如下3种情况:(1)直连方式(2)有一个折点的线相连(3)有两个折点的线相连对于第一种方式.判断起来比较简单,只要两图片相同,在一条直线上.并且之间没有障碍物即可.如图3所示.图3为CLLKanButton类添加FindLine(CPointpl,CPointp2)函数.实现判断是否可直连的功能.源代码如下:啊EPROGRAM.?BOOLCL

16、LKanButton:F;ndLine(CPointp1.CPointp2)fCLLKanDIgparent=(CLLKanDIg)GetParent0;intmax,min:lnti:if(p1.x):=(p2.X)(max=(p1.y>p2.y)?p1.y:p2.V:rain=p1.y<p2.y)?p1.y:p2.V:if(max=rain+1IreturnTRUE;/相邻的两个格子for(i=min+1:l<max;i+)if(parent->mapp1.x=O)returnFALSE:)returnTRUE;)if(p1.Y)=p2.Y)max=(p1.x>

17、;p2.x)?p1.x:p2x:rain=(p1.x<p2.x)?p1.x:p2.x:if(max=min+1)returnTRUE;,相邻的两个格子for(i=min+l:i<max;i+)if(parent一>mapip1.Y】!=O)returnFALSE:)returnTRUE;)returnFALSE:)其【J,pl,p2分别保存有丸后两次点击图片的位信息:为能够得到这些信息.可以先在CLLKanBunon类中为鼠标左键按F添加消息响应.于每个图片部是一个Button.因此在鼠标点山这个Button时,都会有一个this指针指向这个Button,可以千IJ用这个th

18、is指针,将Button的类型信息,位置信息都分别保存下来.只先后点击的是同一种网片时,才调用FindLine等函数来判断足甭能消掉.这样来提高程序的运行效率.雨数是这样运行的.首先要分为横向连接和纵向连接两种类犁分别判断以横向为例,谁的横坐标值小,淮就在左边.m此得到它们大致的位置信息然后从左至右,依次判断它们之问是否有其他的罔片,如果有,则返回FALSE;如果没有.1Jlj表示可以通过直连的方上弋,消掉这-一对图片.对丁第二种方式,判断起来也相对简单.连接它们的折线的折点,横纵坐标定分驯和它们的横纵标相同.如4昕示图4为CLLKanButton类添加FindOneConner(CPoint

19、pl,CPointp21函数.实现判断是否可通过一个折点相连的功能.源代码如下:BOOLCLLKanButtOn:FindOneConner(CPointplCPointD2)CLLKanDtgparent=(CLLKanDIg)GetParent0;intmaxx,maxy,minx,miny;maxx=(p1.x>p2.x)?p1.x:p2.x:maxy=(p1.y>p2.y)?p1.y:p2.vminx=(p1.x<p2.x)?p1.x:p2x:miny=ply<p2.y)?p1.y:p2.v:分别进行判断if(parent一>mapminxmaxy】=0)

20、(mptCross1.X=minx;mptCross1.Y=maxy;if(FindLinepl,mptCross1)&&FindLine(mptCrossl,p2)returnTRUE:.if(parent一>mapmaxxlminy1:=0)mptCross1.X=maxx;mptCross1.Y=miny;if(FindLinepl,mptCross1)(mptCrossl,p2)returnTRUE;)if(parent一>mapminxminy】=0)fmptCross1.X=minx;mptCrosslY=miny;if(FindLine(pl,mptC

21、ross1)(mptCrossl,p2)rettJrnTRUE:&&(FindLine&&(FindLineif(parent->mapmaxxmaxyl=0)mptCross1.X=maxx;mptCross1.Y=maxy;if(FindLine(plm_ptCross1)&&(FindLinemptCrossl,p2)奠_201鹏0.1囊81实用第一智慧密集returnTRUE:)returnFALSE;)折点的横纵坐标一定分别为其中一个图片的横坐标以及另外一个点的纵坐标,由此,就可以定为出折点的位置.值得注意的是,这里可以利用已经写

22、好的FindLine函数,来简化判断过程.对于第3种方式,可以做进一步细分.经常玩连连看的朋友一定知道这样的规律,在游戏进行的初期,通常是先在某一边来找相同的图片.因为在游戏初期,地图还比较完整,即使找到了相同的图片,由于中间有障碍物,也不能消掉,而找到在一侧的相同图片,是不错的突破口,如图5所示.特意编写了判断这样连接方式的函数,力求提高程序运行效率.图5为CLLKanButton类添加FindSide(CPointpl,CPointp2)函数,来实现判断是否可通过一侧相连的功能,源代码如下:BOOLCLLKanButton:FindSide(CPointpl,CPointp2)CLLKan

23、DIgparent=fCLLKanDIg)GetParent0;intmax,min;intiBOOLline=TRUE;BOOLcol=TRUE;if(p1.x)=(p2.x)max=(p1.y>p2.y)?p1.y:p2.y:min=(p1.y<p2.y)?p1.y:p2.y:for(i=min;i<=max;i+)/,上侧if(parent一>mapp1.x一1删!=O)Iine=FALSE;break;)if(1ine)mptCross1.x=p1.x-1:m_ptCross1.Y:p1.V:mptCross2.x=p1.x-1:mptCross2.Y=p2.y

24、:returnTRUE;)else8一:毫置20_1程0.蕾1晡与;_lIine=TRUE;for(i=min;i<=ma:i+)if(parent->mapp1.x+l洲!=O),/下侧line=FALSE;break;)if(1ine)mptCross1.x=p1.x+l:mptCross1.Y=pt.y:mptCross2.x=p1.x+l:mptCross2.Y=p2.y:returnTRUE;)elseline=FALSE;jf(p1.Y)=(p2.Y)max=(p1.x>p2.x)?p1.x:p2.x:min=p1.x<p2.x)?p1.x:p2.x:for

25、(i=min;i<=ma:i+)if(parent->mapip1.y-11col=FALSE;break;)if(co1)m_ptCross1.x=p1.x:mptCross1.y=p1.y-1mptCross2.x=p2.:m_ptCross2.Y=p2.y-1:returnTRUE;)elsecol=TRUE;for(i=min;i<=ma:l+)if(parent->mapip1.y+l】col=FALSE;break;)if(co1)=0)/左侧=O)/右侧.衄啊lPROG删.一IJmptCross1.x=pl.:mptCross1.Y=p1.y+l:m_pt

26、Cross2.x=p2.:mptCross2.Y=p2.y+l:returnTRUE;)elsecol=FALSE;if(1inellco1)returnTRUE:elsereturnFALSE:)函数分别判断上侧,下侧,左侧和右侧,以左侧为例,如果这两个图片的左侧都为空.则可消掉这一对图片.最后.也是最困难的.也就是需要用两个折点才能连接的情况.如罔6所示.I一图6这种情况巾,其中一个折点的横坐标(或纵坐标)一定和其中某图片的横坐标(或纵坐标)相同,另一个折点的横坐标(或纵坐标)一定和另外一幅图片的纵坐标(或横坐标)相同,并且这两个折点还可以直连.基于这一特点,可以这样来判断两图片是否能通过

27、两折而相连.首先从某一图片出发.沿某一方向,如纵向搜索.找到一个空白的位置,一旦这一位置确定下来,就可以分别判断它和起始的图片是否能够直连以及是否能够通过一个折点和另外-幅图片相连如果这两点都能满足,那么就找到了这样的一条路径,可将两图片通过两折相连,如果不满足,则继续搜索,以此类推.直到搜索完毕.如果依旧找不到这样的一条路径.则说明它们不能够通过两折相连.可以为CLLKanButton类添加成员函数FindTwoConner(CPointpl,CPointp2)来实现上述功能,源代码如下:BOOLCLLKanButtOn:Find1.wOCOnner(CPOintpl,CPointp2)in

28、ti:CLLKanDIgparent=fCLLKanDIg)GetParent0;CPointtempPointl=O:CPointtempPoint2=O:/横向for(i=0;i<MAXY;i+)(if(i=p1.y)contInue:tempPoint1.x=p1.:tempPoint1.Y=:mptCross3=tempPointl:if(parent一>maptempPoint1.xtempPoint1.V】=O)if(FindLine(tempPoint1.p1)tempPoint2.x=p2.x:tempPoint2.Y=tempPoint1.y:if(parent一

29、>maptempPoint2.xtempPoint2.V】=O)(if(FindLine(tempPointl,tempPoint2)mptCross4;tempPoint2;if(FindLine(tempPoint2,p2)returnTRUE;)/纵向for(i=0;i<MAXX;i+)if(i=p1.x)continue;tempPoint1.x=i:tempPoint1.Y=p1.VmptCross3=tempPointl:if(parent一>maptempPoint1.xtempPoint1.v】.=O)if(FindLine(tempPoint1.p1)tem

30、pPoint2.x=tempPoint1.x:tempPoint2.Y=p2.y:if(parent->mapItempPoint2.x】【tempPoint2.Y=O)if(FindLine(tempPointl,tempPoint2)mptCross4=tempPoint2;if(FindLine(tempPoint2,p2)returnTRUE;)returnFALSE:)至此,就完成了游戏的核心实现部分.已经可以判断出先后点击的两幅图片是否能消掉,接下来的T作就是将它们真正-一实用第一智慧密集地从游戏界面上消除掉,以及做出消图片时画线的效果.对于消掉图片的操作,要做如下工作:首先

31、,要把消掉的两张图片的类型全都置零,前面已经说过.图片类型为零代表此处没有图片,然后,通过ShowWindowfSW_HIDE)的方式将其隐藏起来,这样给玩家的感觉就像将这两张图片真正地消掉了.完成这一步后,就可以制作消图片时画线的效果.这里可以在主对话框上添加静态空间,设置ID为IDCLINE,并为其关联变量m_line,然后再为工程添加一个类,名为ClineStatic,它继承于Cstatic,用这个类来实现画线的功能.每次需要画线时.可以通过m_line.Invalidate0引起重绘,并且可以在该类内部设置定时器,来限制所画出的线存在的时间.4其他功能经常玩连连看的朋友都知道,在游戏过

32、程中,有可能会出现无图片可消的情况,因此,为了游戏的流畅性,也应该为程序添加自动判断是否有图片可消的功能,如果判断出无图片可消,可以自动重新排序.如果程序能判断出是否有图片可消,也就可以自动找出可消图片,并且自动将其消掉.这样,相当于给程序添加了秘籍,可以设定某一按键或某一菜单项.当按下这一按键或点击这一菜单项时,程序就可以自动地消掉一对图片,在实在找不到时,可以用这一招.这里只介绍寻找可消图片函数的代码,设定消图按键等操作这里就不做介绍了.BOOLCLLKanBuon:Hint()CLLKanDIgparent=fCLLKanDIg)GetParent0;intx1,y1,x2,y2;CPointpl=O:CPointp2=O:for(x1=1:xl<MAXX一1:x1+)for(y1=1:yl<MAXY-1:V1+)for(x2=1:x2<MAXX一1:x2+)for(y2=1:y2<MAXY-1:y2+)p1.x:xl:p1.Y=yl:p2.x=x2;p2.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论