贪食蛇(实训报告)_第1页
贪食蛇(实训报告)_第2页
贪食蛇(实训报告)_第3页
贪食蛇(实训报告)_第4页
贪食蛇(实训报告)_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

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

文档简介

1/23郑州轻工业学院实训报告实训名称:指导教师:姓名:学号:班级:提交日期:

实训目的通过开发一款贪吃蛇小游戏程序,使自己熟练掌握C#编程语言、和面向对象程序设计方法。使自己在掌握VC#面向对象编程理论的基础上,推动自己初步掌握基于VC#的WinForm程序的编程方法,为今后的网络协议编程和Web及Web服务编程打下基础。实训题目使用C#语言在VS平台上编程实现贪食蛇小游戏的运行,如下图所示:功能描述游戏基本功能描述如下:游戏场地是一片矩形透明的区域。蛇由蛇头和蛇身组成。当进入游戏时,任务栏出现如图所示的提示:玩家可以点击鼠标来控制游戏的开始,暂停,继续,退出。也可以使用快捷键:“Q”控制游戏的开始,“W”控制游戏的暂停,“E”控制游戏的继续,“R”控制游戏的退出。当游戏开始之后,草坪中随机出现一颗豆和一条蛇和障碍物,并且蛇不停地移动,蛇移动的方向与蛇头的方向一致,同时显示现在的时间,和游戏运行时间,当游戏结束时游戏运行时间结束,当游戏重新开局时:时,分,秒分别清零。当游戏暂停之后,蛇停止移动。当蛇移动时,玩家可以使用“↑”、“↓”、“←”和“→”四个方向键改变蛇的移动方向。当蛇头与豆的位置重合时,豆被蛇吃掉,同时在草坪中再生成一颗新的豆,蛇身增加一节,同时游戏中分数增加,当分数达到5的倍数时,游戏等级提升,游戏速度也会相应的加快。当蛇头碰到蛇身时,则咬断蛇身,后半部分的蛇身消失,同时分数减为0,但是游戏等级不会发生改变,速度也不会因此发生改变。当蛇头碰到草坪四周,或者是红色的石头时,蛇立即毙命,游戏结束,提示玩家是否再来一局,如图所示:需求分析根据功能描述可知,次小游戏的系统描述图如下:接口蛇玩家接口蛇玩家豆豆草坪草坪定义数据如下:草坪(Lawn):草坪是贪吃蛇游戏的场地。蛇,豆和石头只能存在于草坪范围之内。草坪具有大小和颜色等属性。蛇(Snake):在贪吃蛇游戏中,蛇由若干节组成,其中第一节是蛇头,其余是蛇身。在游戏过程中,仅有一条蛇,并且蛇在不停地移动。如果蛇吃了豆,则蛇生长一节。如果蛇头碰到蛇身,则咬断蛇身,后半部分的蛇身消失。分数也随即清零,游戏运行时间停止。如果蛇头离开草坪,或者与石头相碰撞,则蛇死亡,游戏结束。蛇具有长度、颜色、运动方向、每一节的位置等属性。豆(Bean):在贪吃蛇游戏中,豆是蛇的食物。在游戏过程中,有且仅有一颗豆。如果蛇吃了豆,则重新生成一颗豆。豆具有位置、大小和颜色等属性。石头(Stone):石头是妨碍蛇正常通过的障碍物,如果蛇接触到石头,则游戏结束。石头的出现具有随机性。石头具有长度,颜色,随机位置等属性。设计说明根据需求分析可知,Snake的每一节都有位置和大小等属性。而Bean也具有这两个属性。抽象出二者的共同特征,抽象出一般类Block,用于描述一个块。Block派生出Bean和SnakeBlock两个类,其中SnakeBlock类用于描述蛇的一节。为了使游戏的运行更易于控制,定义Game类用于启动、暂停和继续游戏。根据需求分析可知,Lawn仅包含大小和颜色两个属性。为了减少类的数量,可将其大小和颜色等属性添加到Game类中。综上所述,在贪吃蛇游戏中,有Block(块)、Bean(豆)、SankeBlock(节)、Snake(蛇)、Game(游戏)和MainForm(用户接口)六个类。贪吃蛇游戏的逻辑模型如下图所示。MainFormMainFormGameBlockBeanSnakeBlockSnake6.源代码Block(块)类编码Block是用来构成Bean(豆)和Snake(蛇)的最基本的单位,是Bean和SnakeBlock的基类。Block类的参考代码如下。usingSystem;usingSystem.Drawing;namespaceHungrySnake{classBlock{protectedPointorigion;//Block的左上顶点publicconstintWIDTH=10;//Block的宽度publicconstintHEIGHT=10;//Block的高度protectedColorcolor;//Block的颜色publicBlock(){origion=newPoint(0,0);color=newColor();}publicBlock(intx,inty,Color_color){origion=newPoint(x,y);color=_color;}publicPointOrigion{get{returnorigion;}}publicvoidDisplay(Graphicsg){SolidBrushbrush=newSolidBrush(color);g.FillRectangle(brush,origion.X,origion.Y,WIDTH,HEIGHT);Penpen=newPen(Color.Black);g.DrawRectangle(pen,newRectangle(origion.X,origion.Y,WIDTH-1,HEIGHT-1));}publicvoidClear(Graphicsg,ColorbackGroundColor){SolidBrushbrush=newSolidBrush(backGroundColor);g.FillRectangle(brush,origion.X,origion.Y,WIDTH,HEIGHT);}}}2.Bean(豆)类编码Bean表示豆,是由Block派生而来的。Bean类的参考代码如下。usingSystem;usingSystem.Drawing;namespace贪食蛇{classBean:Block{publicstaticintscore=0;publicstaticintgrade=0;publicBean(Color_color){origion=newPoint(0,0);color=_color;}publicvoidCreat(Graphicsg,ColorbackGroundColor,intlawnWidth,intlawnHeight,Snakesnake,Pointstonepoint,Pointstonepoint2){Clear(g,backGroundColor);boolbGetAPosition=false;//是否找到生成豆的位置Randomrandom=newRandom();while(!bGetAPosition){origion.X=random.Next(0,lawnWidth-1)/WIDTH*WIDTH;origion.Y=random.Next(0,lawnHeight-1)/HEIGHT*HEIGHT;if((((origion.X>=stonepoint.X&&origion.X<=stonepoint.X+149)&&(origion.Y>=stonepoint.Y&&origion.Y<=stonepoint.Y+9)))||(((origion.X>=stonepoint2.X&&origion.X<=stonepoint2.X+149)&&(origion.Y>=stonepoint2.Y&&origion.Y<=stonepoint2.Y+9)))){origion.X-=50;origion.Y-=50;}inti;for(i=0;i<snake.Length;i++){if(origion==snake.blocks[i].Origion)break;}if(i==snake.Length){bGetAPosition=true;score++;}if(score%5==0&&score!=0){grade++;}}Display(g);}}}3.SnakeBlock(节)类编码 SnakeBlock表示蛇的一节,是由Block派生而来的。SnakeBlock类的参考代码如下:usingSystem;usingSystem.Drawing;namespace贪食蛇{classSnakeBlock:Block{privateboolisHead;publicboolIsHead{get{returnisHead;}}publicSnakeBlock(intx,inty,Color_color,bool_isHead){origion=newPoint(x,y);color=_color;isHead=_isHead;}publicvoidChangeHeadToBody(){if(isHead)isHead=false;}publicvoidDisplay(Graphicsg,Directiondirection){base.Display(g);if(isHead){//绘制蛇眼SolidBrushbrush=newSolidBrush(Color.Brown);switch(direction){caseDirection.Up:caseDirection.Down:g.FillRectangle(brush,origion.X+WIDTH/4,origion.Y+HEIGHT/2,2,2);g.FillRectangle(brush,origion.X+WIDTH/4*3,origion.Y+HEIGHT/2,2,2);break;caseDirection.Left:caseDirection.Right:g.FillRectangle(brush,origion.X+WIDTH/2,origion.Y+HEIGHT/4,2,2);g.FillRectangle(brush,origion.X+WIDTH/2,origion.Y+HEIGHT/4*3,2,2);break;}}}}}4.Snake(蛇)类编码 usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Drawing;namespace贪食蛇{publicenumDirection{Up,Down,Left,Right};classSnake{privateintlength;publicDirectiondirection;privateColorcolor;publicList<SnakeBlock>blocks;privateconstintINIT_LENGTH=3;publicintLength{get{returnlength;}}publicSnake(Color_color,Direction_direction){direction=_direction;color=_color;blocks=newList<SnakeBlock>();}publicvoidCreat(Graphicsg,ColorbackGroundColor,intlawnWidth,intlawnHeight){Clear(g,backGroundColor);blocks.Clear();length=INIT_LENGTH;intx=50;//防止石头与蛇相遇,固定蛇的初始位置inty=440;//防止石头与蛇相遇,固定蛇的初始位置Randomrandom=newRandom();blocks.Add(newSnakeBlock(x,y,color,true));switch(direction){caseDirection.Up:for(inti=1;i<length;i++){blocks.Add(newSnakeBlock(x,y+Block.HEIGHT*i,color,false));}break;caseDirection.Down:for(inti=1;i<length;i++){blocks.Add(newSnakeBlock(x,y-Block.HEIGHT*i,color,false));}break;caseDirection.Left:for(inti=1;i<length;i++){blocks.Add(newSnakeBlock(x+Block.WIDTH*i,y,color,false));}break;caseDirection.Right:for(inti=1;i<length;i++){blocks.Add(newSnakeBlock(x-Block.WIDTH*i,y,color,false));}break;}Display(g);}publicvoidGrow(){intx=2*blocks[blocks.Count-1].Origion.X-blocks[blocks.Count-2].Origion.X;inty=2*blocks[blocks.Count-1].Origion.Y-blocks[blocks.Count-2].Origion.Y;blocks.Insert(length,newSnakeBlock(x,y,color,false));length++;}publicvoidMove(){intx=0;inty=0;blocks[0].ChangeHeadToBody();switch(direction){caseDirection.Up:x=blocks[0].Origion.X;y=blocks[0].Origion.Y-Block.HEIGHT;break;caseDirection.Down:x=blocks[0].Origion.X;y=blocks[0].Origion.Y+Block.HEIGHT;break;caseDirection.Left:x=blocks[0].Origion.X-Block.WIDTH;y=blocks[0].Origion.Y;break;caseDirection.Right:x=blocks[0].Origion.X+Block.WIDTH;y=blocks[0].Origion.Y;break;}blocks.Insert(0,newSnakeBlock(x,y,color,true));blocks.RemoveAt(blocks.Count-1);}publicvoidDisplay(Graphicsg){for(inti=0;i<length;i++){blocks[i].Display(g,direction);}}publicvoidClear(Graphicsg,ColorbackGroundColor){for(inti=0;i<length;i++){blocks[i].Clear(g,backGroundColor);}}publicvoidRemoveAfter(Graphicsg,ColorbackGroundColor,intblockNum){for(inti=length-1;i>blockNum-1;i--){blocks[i].Clear(g,backGroundColor);blocks.RemoveAt(i);length=blockNum;}}publicboolCanEatBean(Beanbean){if(blocks[0].Origion==bean.Origion)returntrue;elsereturnfalse;}publicboolSnakeMeetStone(Pointstonepoint){if((((blocks[0].Origion.X>=stonepoint.X&&blocks[0].Origion.X<=stonepoint.X+149)&&(blocks[0].Origion.Y>=stonepoint.Y&&blocks[0].Origion.Y<=stonepoint.Y+9))))returntrue;elsereturnfalse;}publicboolSnakeMeetStone2(Pointstonepoint2){if(((blocks[0].Origion.X>=stonepoint2.X&&blocks[0].Origion.X<=stonepoint2.X+149)&&(blocks[0].Origion.Y>=stonepoint2.Y&&blocks[0].Origion.Y<=stonepoint2.Y+9)))returntrue;elsereturnfalse;}publicintCanEatSnake(){for(inti=3;i<blocks.Count;i++){if(blocks[0].Origion==blocks[i].Origion)returni;}return0;}publicvoidEatBean(Beanbean,Graphicsg,ColorbackGroundColor,intlawnWidth,intlawnHeight){Pointstonepoint=Game.stonepoint;Pointstonepoint2=Game.stonepoint2;bean.Clear(g,backGroundColor);Grow();bean.Creat(g,backGroundColor,lawnWidth,lawnHeight,this,stonepoint,stonepoint2);}publicboolIsAlive(intlawnWidth,intlawnHeight){if(blocks[0].Origion.X<0)returnfalse;if(blocks[0].Origion.Y<0)returnfalse;if(blocks[0].Origion.X+Block.WIDTH>lawnWidth)returnfalse;if(blocks[0].Origion.Y+Block.HEIGHT>lawnHeight)returnfalse;elsereturntrue;}}}5.Game(游戏)类设计Game控制游戏的运行,负责在游戏开始时生成Bean和Snake,以及负责在游戏运行中Snake的移动、Snake的生长、Bean的重生,以及分数的增加,并随时检测Snake的生死状态。Game类的参考代码如下:usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Drawing;namespace贪食蛇{classGame:Block{publicstaticPointstonepoint;publicstaticPointstonepoint2;publicSnakesnake;publicBeanbean;publicboolisSnakeAlive;publicintlawnWidth;publicintlawnHeight;publicGame(int_lawnWidth,int_lawnHeight){Randomrandom=newRandom();intx=random.Next(0,_lawnWidth-1)/Block.WIDTH*Block.WIDTH;inty=random.Next(0,_lawnHeight-1)/Block.HEIGHT*Block.HEIGHT;Directiondirection=(Direction)random.Next(1,4);snake=newSnake(Color.YellowGreen,direction);bean=newBean(Color.Pink);isSnakeAlive=false;lawnWidth=_lawnWidth;lawnHeight=_lawnHeight;}publicvoidBegin(Graphicsg,ColorbackGroundColor,intlawnWidth,intlawnHeight){g.Clear(Color.Turquoise);intstoneway_X,stoneway_Y;intstoneway_X2,stoneway_Y2;Randomrandom=newRandom();intstoneway1_X=random.Next(2,29);//让障碍物以10个单位生成intstoneway1_Y=random.Next(2,39);//让障碍物以10个单位生成intstoneway2_X=random.Next(10,30);//让障碍物以10个单位生成intstoneway2_Y=random.Next(39,47);//让障碍物以10个单位生成int[]array_x={stoneway1_X,stoneway2_X};int[]array_y={stoneway1_Y,stoneway2_Y};inti=random.Next(0,2);intj=random.Next(0,2);stoneway_X=10*array_x[i];stoneway_Y=10*array_y[i];stoneway_X2=10*array_x[j];stoneway_Y2=10*array_y[j];isSnakeAlive=true;snake.Clear(g,backGroundColor);snake.Creat(g,backGroundColor,lawnWidth,lawnHeight);bean.Creat(g,backGroundColor,lawnWidth,lawnHeight,snake,stonepoint,stonepoint2);g.FillRectangle(newSolidBrush(Color.Red),stoneway_X,stoneway_Y,150,10);//障碍物的显示g.FillRectangle(newSolidBrush(Color.Red),stoneway_X2,stoneway_Y2,150,10);//障碍物的显示stonepoint.X=stoneway_X;stonepoint.Y=stoneway_Y;stonepoint2.X=stoneway_X2;stonepoint2.Y=stoneway_Y2;Bean.score=0;Bean.grade=0;}publicvoidOnTime(Graphicsg,ColorbackGroundColor,intlawnWidth,intlawnHeight){if(isSnakeAlive){snake.Clear(g,backGroundColor);snake.Move();snake.Display(g);bean.Display(g);if(snake.CanEatBean(bean)){bean.Clear(g,backGroundColor);snake.EatBean(bean,g,backGroundColor,lawnWidth,lawnHeight);bean.Display(g);}intblockNum=snake.CanEatSnake();if(blockNum>0){snake.RemoveAfter(g,backGroundColor,blockNum);Bean.score=0;}if((!snake.IsAlive(lawnWidth,lawnHeight))||(snake.SnakeMeetStone(stonepoint))||(snake.SnakeMeetStone2(stonepoint2)))isSnakeAlive=false;}}}}6.MainForm(主界面)类设计MainForm可通过继承System.Windows.Forms.Form实现,通过向MainForm中添加控件及设置控件的属性系统会自动向MainForm类中添加相应的对象字段,如本程序的menuStrip1和timer1等。1)添加属性:添加属性game,来控制游戏的开始和运行,参考代码如下:privateGamegame;2)修改构造函数:在构造函数的最后对属性game进行实例化,参考代码如下:game=newGame(lawn.Width,lawn.Height);3)Panal容器:Panel容器作为游戏运行的场地。蛇(Snake)豆(Bean)和石头(Stone)都在Panel容器中绘制。Panel容器的添加步骤如下:在MainForm中添加一个Panel容器。拖动Panel容器的大小,使其充满整个窗体。修改Panel容器的属性Name=lawn。修改Panel容器的属性BackColor=Turquoise。4)Timer组件:Timer组件用于在用户定义的时间间隔引发事件。Timer组件的添加步骤如下:在MainForm中添加一个Timer组件。修改Timer组件的属性Enalbed=false。双击,生成Tick事件。Tick事件的参考代码如下:label4.Text=DateTime.Today.ToShortDateString();label5.Text=DateTime.Now.ToLongTimeString();if(game.isSnakeAlive){Graphicsg;g=lawn.CreateGraphics();game.OnTime(g,lawn.BackColor,lawn.Width,lawn.Height);if(!game.isSnakeAlive){if(MessageBox.Show("游戏结束!!!\n需要再来一局吗?","提示",MessageBoxButtons.YesNo,MessageBoxIcon.Warning)==DialogResult.Yes){game.Begin(g,lawn.BackColor,lawn.Width,lawn.Height);timer1.Enabled=true;label8.Enabled=true;label9.Enabled=false;}}label2.Text=Bean.score.ToString();label11.Text=Bean.grade.ToString();timer1.Interval=(150-Bean.grade*20);label13.Text=timer1.Interval.ToString();}在MainForm中再添加一个Timer组件。双击生成Tick事件。Tick事件的参考代码如下:privatevoidtimer2_Tick(objectsender,EventArgse){if(game.isSnakeAlive){timer2.Interval=1000;label15.Text=string.Format("{0}:{1}:{2}",hour.ToString(),min.ToString(),sec.ToString());sec++;if(sec==60){min++;sec=0;}if(min==60){hour++;min=0;}if(!game.isSnakeAlive)timer2.Enabled=true;}}5)Label控件:Label控件可用于提供用户可以使用的功能。Label控件的添加步骤如下:在MainForm中添加一个label。分别修改label控件的属性。分别设置label控件的Text属性,使其分别显示为:开始游戏(Q),退出游戏(R),暂停(W),继续(E),游戏得分等一系列控件属性。双击“开始游戏(Q)”,生成Click事件。Click事件的参考代码如下:Graphicsg;g=lawn.CreateGraphics();game.Begin(g,lawn.BackColor,lawn.Width,lawn.Height);timer1.Enabled=true;timer2.Enabled=true;label8.Enabled=true;label9.Enabled=false;双击暂停“(W)”,生成Click事件。Click事件的参考代码如下:timer1.Enabled=false;label8.Enabled=false;label9.Enabled=true;双击菜单项“继续(E)”,生成Click事件。Click事件的参考代码如下:timer1.Enabled=true;label8.Enabled=true;label9.Enabled=false;双击菜单项“退出游戏(R)”,生成Click事件。Click事件的参考代码如下:if(MessageBox.Show("确实要退出游戏吗?","提示",MessageBoxButtons.YesNo,MessageBoxIcon.Information)==DialogResult.Yes)this.Close();6)KeyDown事件:在贪吃蛇游戏中,使用“↑”、“↓”、“←”和“→”四个方向键改变蛇的移动方向,使用“Q”控制游戏的开始,“E”控制游戏的继续,“W”控制游戏的暂停,“R”控制游戏退出。KeyDown事件用于在用户按方向键时,提供改变蛇移动方向;按此几个快捷键时,控制游戏的各种功能。KeyDown事件的添加步骤如下:双击事件KeyDown,生成MainForm的KeyDown事件。KeyDown事件的参考代码如下:stringS="";S=e.KeyCode.ToString();switch(S){case"Q":Graphicsg;g=lawn.CreateGraphics();game.Begin

温馨提示

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

评论

0/150

提交评论