连连看游戏一、课程设计题目基于C#的连连看设计二、需求分析生活在节奏越来越快的城市里,适量的游戏可以为我们舒缓疲劳,带来愉悦的心情。不管你走到哪个游戏网站,连连看游戏总在排名的前5,休闲、趣味、益智是连连看玩不厌的精华,是一款适合大众的经典网络休闲小游戏。在讨论后我们小组最后选定做连连看这个小游戏。本系统是一款简单的单机版游戏,只要将相同花色的两张牌用三根以内的直线连在一起就可以消除,当游戏中已没有满足条件的图案时,点击重列可重新排序,规则简单容易上手。游戏速度节奏快,画面清晰可爱,老少皆宜,因此越来越受大众的欢迎。游戏规则如下:(1)概要:玩家可以将2个相同图案的牌连接起来,连接线不多于3根直线,就可以成功将两个牌消除。(2)操作:第一次使用鼠标点击游戏界面中的牌,该牌此时为“被选中”,以特殊方式显示;再次以鼠标点击其他牌,若该牌与被选中的牌图案相同,且把第一个牌到第二个牌连接起来,中间的直线不超过3根,则消除这一对牌,否则第一个牌回复成未被选中状态,而第二个牌变成被选中状态。(3)胜利条件:将游戏界面上的牌全部消除掉。(4)失败条件:到规定时间,界面上的牌仍未全部消掉。三、概要设计1.方案选择在概要设计阶段,有两种方案可供选择:第一种方案是所有出现的图像的种类数和重复次数都是软件约定的,这样就在无意中降低了玩家在游戏过程中乐趣,最后致使玩家不想继续玩下去。我们参考了网络上的连连看游戏,考虑到游戏的娱乐性。所以参考网络上流行的连连看游戏,设计出第二种方案。第二种方案:在同一区域中,图片出现的种类数和重复次数是可以由玩家选择的,时间由软件约定。不过玩家选择的种类数和重复次数必须是偶数才可以顺利完成游戏,否则游戏虽然可以正常运行,但无法完成游戏。2.系统设计针对上面的需求分析,我们把整个软件分成两个模块:1、整体界面的设计和图片的随机生成;2、图片路径判断函数;以下就是系统结构图:连连看系统结构图3.基本思路3.1游戏画面问题的思路画面,对于设计者来说,可以算是最简单的地方;但对于玩家,这却是最重要的,一般玩家不会关心你是怎么实现的,他所关心的是画面的美观,漂亮,是否能让人赏心悦目。3.2获取图片位置的思路通过数组从图片库随即获取规定个数得到图片,随机分布在画布上。图片个数一定是偶数个。3.3路径判断的思路连连看所要求的是:1:两个目标是相同的2:两个目标之间连接线的折点不超过两个。(连接线由x轴和y轴的平行线组成)那么分析一下连接的情况可以看到,一般分三种情况1:直线相连2:一个折点3:两个折点:可以发现,如果有折点,每个折点必定有且至少有一个坐标(x或者y)是和其中一个目标点是相同的,也就是说,折点必定在两个目标点所在的x方向或y方向的直线上。所以设计思路就是:连连看界面设计和图片的随机生成模块模块图片路径判断函数假设目标点p1,p2,如果有两个折点分别为z1,z2那么,所要进行的是1:如果验证p1,p2直线连线,则连接成立2:搜索以p1,p2的x,y方向四条直线(可能某两条直线会重合)上的有限点,每次取两点作为z1,z2,验证p1到z1/z1到z2/z2到p2是否都能直线相连,是则连接成立。四、详细设计4.1主界面的设计由于这个程序的界面并不是很复杂,所以用到的控件也不多,主要核心内容还是后台的代码设计。图片的随机生成主要是用到一个random()函数将随机数赋值给flag[]数组中的每个元素,然后根据数组元素值,来显示图片。4.1.1界面的设计程序主体界面1、色彩上:总结人们的视觉习惯和色彩对眼睛的健康影响,决定对于画布采用黑色背景,神秘而大方;右边的控制区采用天蓝色,配合左边纯黑的背景,就像黑夜中的蓝天,纯洁而大气。2、功能上:背景就是窗体,右侧是一个groupbox控件,用来放置控制按钮,下方是一个progressbar控件,用来显示时间条。4.2图片的随机生成实现这个功能要分很多个步骤:1、程序运行时即载入游戏需要的N张图片,默认情况下图片种类数是18,重复数是4(重复数必须是偶数),并且可以选择是否重列。通过一个循环,加载随即的选择N种图片。具体载入图片的代码如下:privatevoidIniteBmp(intmaxnum){g_g=this.CreateGraphics();for(inti=0;iMAPWIDTH;i++)for(intj=0;jMAPHEIGHT;j++)gmap[i,j]=0;IniteRandomMap(refgmap,maxnum);AI=newKernal(refgmap);for(inti=0;imaxnum;i++){ResourceManagerrm=newResourceManager(LLK.data,Assembly.GetExecutingAssembly());img[i]=(Image)rm.GetObject(i.ToString()+.bmp);//img[i]=(Image)Bitmap.FromFile(Images\\+(i+1).ToString()+.bmp);}for(inti=0;i6;i++){//bombimg[i]=(Image)Bitmap.FromFile(Images\\B+(i+1).ToString()+.bmp);}}}2、当确认游戏开始时,通过画图过程完成图片生成,画图的过程代码如下:privateboolCheckWin(refint[,]map){boolWin=true;for(inti=0;iMAPWIDTH;i++)for(intj=0;jMAPHEIGHT;j++)if(map[i,j]!=0)Win=false;returnWin;}privatevoidIniteRandomMap(refint[,]map,intnum){Randomr=newRandom();while(num0){for(inti=0;imultipic;i++){intxrandom=r.Next(19);intyrandom=r.Next(11);if(map[xrandom,yrandom]==0){map[xrandom,yrandom]=num;}Elsei--;}num--;}}privatevoidFreshMap(refint[,]map){Randomr=newRandom();for(inti=0;iMAPWIDTH;i++)for(intj=0;jMAPHEIGHT;j++){if(gmap[i,j]!=0){intx=r.Next(19);inty=r.Next(11);inttemp=gmap[x,y];gmap[x,y]=gmap[i,j];gmap[i,j]=temp;}}TransportMap(refgmap);}privatevoidTransportMap(refint[,]map){for(inti=0;iMAPWIDTH;i++)for(intj=0;jMAPHEIGHT;j++){AI.GiveMapValue(i,j,map[i,j]);}}//在指定位置画指定图privatevoidDraw(Graphicsg,ImagescrImg,intPicX,intPicY){g.DrawImage(scrImg,newPoint(PicX,PicY));}privatevoidForm1_Paint(objectsender,PaintEventArgse){g_g.DrawLine(newPen(newSolidBrush(Color.DeepSkyBlue),5),0,11*34+5,19*34,11*34+5);if(bStart){for(inti=0;iMAPWIDTH;i++)for(intj=0;jMAPHEIGHT;j++){if(gmap[i,j]!=0){Draw(g_g,img[gmap[i,j]-1],i*PICWIDTH,j*PICHEIGHT);}}}}4.3单击控件的事件触发总共有两个单击按钮。分别是:开始游戏(进入游戏状态)、重列(重新加载图片)。开始游戏实现代码如下:boolstarttimer=false;privatevoidbutton1_Click_1(objectsender,EventArgse){//处理Processbarif(!starttimer){progressBar1.Value=PBMAX;pbtimer.Interval=500;pbtimer.Start();starttimer=true;}//处理分数score=0;picnum=Convert.ToInt16(textBox1.Text);multipic=Convert.ToInt16(textBox2.Text);if(picnum*multipic209){MessageBox.Show(游戏区域内最多只有209个空,您选的数据太多,请重新选择!);textBox1.Text=18;textBox2.Text=4;return;}IniteBmp(picnum);if(bStart){MessageBox.Show(游戏已在运行);return;}else{bStart=true;this.Invalidate();music.Play(Sounds\\bg-03.mid);}}重列实现代码如下:privatevoidRefreshMap(refint[,]map){if(bStart){for(inti=0;iMAPWIDTH;i++)for(intj=0;jMAPHEIGHT;j++){if(gmap[i,j]!=0){Draw(g_g,img[gmap[i,j]-1],i*PICWIDTH,j*PICHEIGHT);}}}}privatevoidbutton2_Click(objectsender,EventArgse){refreshplayer.Play();//Thread.Sleep(100);//bombplayer.Play();FreshMap(refgmap);this.Invalidate();}4.4得分设置本游戏,我们小组讨论后决定采用全新计分方式,对于不同的路径会得到不同的分数,使人们在寻找相同图片的同时还要注意路径的选择,更增加了游戏的趣味性,具体规则:直连得10分,一个拐点得20,两个拐点得40。用一个Label控件存储得分。实现代码:switch(corner[2].X){case1:score+=20;//一个拐点加20;g_g.DrawLine(pen,newPoint(p1.X*31+15,p1.Y*34+17),newPoint(corner[0].X*31+15,corner[0].Y*34+17));g_g.DrawLine(pen,newPoint(p2.X*31+15,p2.Y*34+17),newPoint(corner[0].X*31+15,corner[0].Y*34+17));Thread.Sleep(100);EraseBlock(g_g,p1,p2);g_g.DrawLine(bkpen,newPoint(p1.X*31+15,p1.Y*34+17),newPoint(corner[0].X*31+15,corner[0].Y*34+17));g_g.DrawLine(bkpen,newPoint(p2.X*31+15,p2.Y*34+17),newPoint(corner[0].X*31+15,corner[0].Y*34+17));break;case2:score+=40;//两个拐点加40;Point[]ps={newPoint(p1.X*31+15,p1.Y*34+17),newPoint(corner[1].X*31+15,corner[1].Y*34+17),newPoint(corner[0].X*31+15,corner[0].Y*34+17