




已阅读5页,还剩14页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于VC#.NET的贪吃蛇游戏的目录1. 实验目的2. 实验任务与要求2.1实验内容2.2实验要求2.3实验环境3. 设计方案3.1程序功能3.2设计思想3.3设计总体流程图3.4设计的具体实现4. 程序测试4.1测试内容与结果4.2程序运行效果图5. 实验总结参考文献附录 附录A:主要源程序 附录B:软件使用说明书1. 实验目的:l 复习、巩固VC#.NET的基础知识,进一步加深对VC#.NET技术的理解和掌握;l 课程设计为学生提供了一个既动手又动脑,独立实践的机会,将课本上的理论知识和实际有机的结合起来,锻炼学生的分析解决实际问题的能力。l 培养学生在项目开发中团队合作精神、创新意识及能力2. 实验任务与要求2.1 实验内容贪吃蛇游戏开发,首先它可以为大家提供一种当前比较流行的休闲小游戏。贪吃蛇是家喻户晓的益智类小游戏,选择这个题目一是为了将自己的所学知识加以运用,二是一直以来贪吃蛇这个游戏就深深地吸引着很多人,它的制作方法对于很多同学而言都是很神秘的。所以我们希望通过这学期所学知识把它剖析开来,真真正正的了解它的本质和精髓。在这次学习中我们将从实践和实际的项目中提高自己的编程能力。因此决定选择这个题目作为VC#.NET的课程设计。最后一部分就是游戏的模块划分,根据分析,贪吃蛇这个程序一共要实现如下几个功能,包括游戏方面开始游戏、暂停游戏以及停止游戏,游戏设置(蛇的颜色、食物的颜色、游戏难度设置),游戏帮助(游戏控制说明)与积分。2.2实验要求l 对系统进行功能模块分析、控制模块分析正确,符合课题要求,实现相应功能;可以加以其他功能或修饰,使程序更加完善、合理;l 系统设计要实用,采用模块化程序设计方法,编程简练、可用,功能全面;l 说明书、流程图要清楚;l 记录设计情况(备查,也为编写设计说明书作好准备);2.3实验环境WindowsXP操作系统,VS.NET2005开发环境。3. 设计方案3.1程序功能游戏界面:1)开始游戏(加载并开始)2)暂停游戏(从当前进度结束)3)重新开始(在某一时刻暂停后可以继续接着玩)4)停止游戏(停止正在玩的游戏,再次开始时是重新开始)游戏设置:1)蛇的颜色(白色、蓝色、黄色)2)游戏难度设置(1级、2级、3级)3)游戏帮助(游戏控制说明)4)积分(每次吃掉一个食物增加5分,并显示出来)3.2设计思想首先,该游戏有两个类,以及一个枚举类型,列举了蛇块移动的四个方向;一个蛇块类,用来描述蛇块的信息和将自身绘制到画布上;另一个是画蛇类,画蛇类里要有开始函数,调用开始函数可以使游戏开始,游戏死亡函数,让游戏会结束,既然是贪吃蛇,就少不了蛇的移动,食物的生成,游戏是动态的,在贪吃蛇吃食物的过程中,每吃一个界面就需要更新一下,当然需要用到定时更新函数和刷新画板,保持游戏的动态和连贯性。大概思想是这样的,里面需要注意的是,蛇什么情况下死亡,有两种情况,第一,蛇撞到墙,第二,舌头蛇尾相接。蛇在移动时,如果遇到食物,就把食物吃了,蛇的身子会长一节,如果前方没有食物,就响应键盘,按照方向移动。蛇可以沿着墙壁走,但是沿着墙壁走和撞墙是有区别的,这些细节要区分开。其次,设计主界面,即一个Form框,在框里放一个PictureBox框,设置画布类来作为贪吃蛇游戏的背景。界面里要有开始按钮,暂停、重新开始、退出这些按钮。开始就是要初始化并加载游戏,暂停是当游戏在进行时,可以短时间内终止,重新开始,是继续暂停时的游戏,退出要将该游戏系统关闭,便可以退出。为了满足游戏的动态画面效果和适应不同级别的人群,要设置游戏蛇块颜色的菜单,食物颜色的菜单,以及游戏等级菜单,来最大可能地满足不同需求的人群,扩大市场的需求,为了更细心体贴,再设置一个帮助菜单更好,引导人们更方便地使用一些功能。大体上就是这样吧,有了思想在敲打代码的过程中就有了目标,思路会清晰,不过一些细节性的问题要注意。3.3设计总体流程图载入游戏并初始化判断是否开始游戏等级蛇颜色设置退出否蛇开始移动是根据键盘控制蛇移动方向蛇头和食物坐标是否重合随机生成下一个食物是否蛇头是否撞墙以及头尾是否相接游戏结束是否游戏菜单帮助选择哪个级别1级2级3级选择颜色白色蓝色黄色3.4设计的具体实现1)、蛇块类把蛇分成一块一块,一个蛇相当于有若干个块,蛇块类就是用来描述每块的信息。a)、蛇块类的私有变量:private Color _color;/颜色 private int _size;/大小 private Point _point;/坐标b)、构造函数: public snakeBlock(Color color, int size, Point p) c)、获取记录蛇块的坐标:public Point Point/属性 d)、Paint函数:public virtual void Paint(Graphics g) Paint函数根据坐标以及蛇块大小计算出实际绘图的坐标,进行绘图,蛇块是一个正方形(矩形),我们用矩形绘制,在代码中我们看到,绘制的大小比size小1个像素,这么做的原因是为了突出蛇块与蛇块之间的间隙,也就是说蛇块与蛇块之间有1个像素的间隙,这就是我们看到游戏效果图中的蛇块是一段一段的原因。 2)、画蛇类画蛇类是真个游戏的核心处理类,里面定义了画布的大小,背景色,蛇块列表以及游戏速度,移动方向等属性另外还提供了timer计时器,用于定时更新蛇块坐标位置,以及如何在画面上画图的函数。a)、Start函数用于开始游戏,这个函数的内部其实就是设定食物,以及触发计时器。这里面定义了计时器的事件触发间隔,是通过level然后找到speed数组里的对应毫秒值设定的。然后触发事件是OnBlockTimedEvent,最后是启动计时器开始计时。代码如下:public void Start() this._food = GetFood();/生成一个食物 timerBlock = new System.Timers.Timer(_speedthis._level); timerBlock.Elapsed += new System.Timers.ElapsedEventHandler(OnBlockTimedEvent); timerBlock.AutoReset = true; timerBlock.Start(); b)、OnBlockTimedEvent函数是计时器的执行函数,这个函数用于更新蛇块信息列表,以及检测游戏是否结束,函数内部调用了两个函数,一个是Move函数,一个是CheckDead函数。代码如下:private void OnBlockTimedEvent(object source, ElapsedEventArgs e)/定时更新 this.Move(); if (this.CheckDead() this.timerBlock.Stop(); /停止引发事件 this.timerBlock.Dispose(); /释放资源 int score=(this._blocks.Count-1)*5; System.Windows.Forms.MessageBox.Show(游戏失败,得分为: + score, Game Over!); c)、checkDead函数用于检测游戏是否结束,检测是否结束分两种情况,一种是撞上边界,即蛇头坐标超出画布范围,一种是蛇头撞上了蛇身,也就是蛇头的坐标和蛇身的某个坐标重合,通过for循环来检查第二种情况。代码如下:private bool CheckDead() /检查游戏是否结束 snakeBlock head = (snakeBlock)(this._blocks0);/超出画布范围 if (head.Point.X-1 0 | head.Point.Y-1 = this._width -1| head.Point.Y = this._height-1) return true; for (int i = 1; i this._blocks.Count; i+) snakeBlock b = (snakeBlock)this._blocksi;/是否头尾相接 if (head.Point.X = b.Point.X & head.Point.Y = b.Point.Y) this._isGameOver = true; return true; this._isGameOver = false; return false; d)、GetFood函数用于生成下一个食物,其实就是一个蛇块,生成的规则就是,坐标要在画布范围内,并且食物的坐标不能和贪吃蛇的坐标重合,具体代码如下通过for循环检查食物坐标是否和贪吃蛇的蛇块列表ArrayList里的蛇块有冲突。代码如下:private snakeBlock GetFood() /生成下一个食物,也就是下一节蛇块 snakeBlock food = null; Random r = new Random(); bool redo = false; while (true) redo = false; int x = r.Next(this._width); int y = r.Next(this._height); for (int i = 0; i this._blocks.Count; i+) snakeBlock b = (snakeBlock)(this._blocksi); if (b.Point.X = x & b.Point.Y = y) redo = true; if (redo = false) food = new snakeBlock(Color.Gold, this._size, new Point(x, y); break; return food; e)、Move函数用于更新整个蛇块的坐标,我们前面通过将蛇块信息放到ArrayList里来表示贪吃蛇的整个信息,其中根据下标从0到Count-1依次表示各个蛇块的信息,实际代码中增加了吃食物的情况判断,也就是说如果新蛇头的坐标和食物的坐标一致,那么就不做删除原蛇尾的操作了,这样产生的效果就是蛇块列表的长度增加了一个,达到吃食物变长的效果。代码如下:private void Move() /蛇体移动 Point p = new Point(); /下一个位置 snakeBlock head = (snakeBlock)(this._blocks0); if (this._direction = Direction.Up) p = new Point(head.Point.X, head.Point.Y - 1); else if (this._direction = Direction.Down) p = new Point(head.Point.X, head.Point.Y + 1); else if (this._direction = Direction.Left) p = new Point(head.Point.X - 1, head.Point.Y); else p = new Point(head.Point.X + 1, head.Point.Y); /生成新坐标,将成为蛇头 snakeBlock b = new snakeBlock(Color.Red, this._size, p);/如果下一个坐标不是当前食物坐标,那么从蛇块信息列表中删除最后一个蛇块 if (this._food.Point != p) this._blocks.RemoveAt(this._blocks.Count - 1); /如果下一个坐标和食物坐标重合,那么就生成一个新食物 else this._food = this.GetFood(); /把下一个坐标插入到蛇块信息列表的第一个,使其成为蛇头 fen += 5; this._blocks.Insert(0, b); / 将元素插入指定索引处 this.PaintPalette(this._gpPalette); /更新画板 f)、PaintPalette函数需要一个参数,也就是绘图句柄,然后在这个画布上画图也就是我们看到的游戏效果,首先用背景色清空画布,然后画食物,其次是通过for循环将贪吃蛇的每个蛇块画在画布上,以此达到游戏效果。代码如下:public void PaintPalette(Graphics gp) /更新画板 gp.Clear(this._bgColor); /清除整个绘图面并以指定背景色填充 this._food.Paint(gp); foreach (snakeBlock b in this._blocks) b.Paint(gp); g)、构造函数很简单就是设定类属性值,还有初始化蛇块列表ArrayList,然后需要说明的是你得手动生成一个蛇块放到列表里面,否则连个蛇头都没有怎么玩啊。this._blocks.Insert(0, (new Block(Color.Red, this._size, new Point(width / 2, height / 2);这句话就是在画布的正中央产生一个只有一节的贪吃蛇。代码如下: public snakeMode(int width, int height, int size, Color bgColor, Graphics g,int lvl) / 构造函数 this._width = width; this._height = height; this._bgColor = bgColor; this._gpPalette = g; this._size = size; this._level = lvl; this._blocks = new ArrayList(); this._blocks.Insert(0, (new snakeBlock(Color.Red, this._size, new Point(width / 2, height / 2); this._direction = Direction.Right; 4.程序测试4.1测试内容与结果游戏方面:1)开始:程序运行后,会出来只有一节的红色蛇和一个黄色的食物,并且蛇是静止的。点击开始按钮后,红色的蛇开始运动。所以开始按钮使用正确。2)方向键和WSAD键:蛇开始运行之后,当点击上下左右键(或WSAD)蛇就会按相应的方向运动,由于现实中蛇不会180度的转弯,所以就进行设置,让蛇块只能进行90度的转弯。程序检测时蛇确实会按点击方向运动且不会向相反方向运动,所有方向键使用正确。3)暂停/继续:当程序正在运行时,点击暂停/继续按钮,蛇停在当前的位置,再次点击蛇又从当前位置继续运动。此按钮符合要求,所以暂停/继续按钮使用正确,功能能够实现。4)重新开始:当游戏结束或想重新开始一局时,点击此按钮,游戏又回到最初的状态,一个食物,一个运动着的红色蛇块,且游戏积分清零。所以重新开始功能能够实现。5)退出:点击退出按钮,游戏窗口关闭,回到程序界面。所以退出功能可以实现。游戏设置:1)游戏等级设置:当在游戏还没开始时点击了菜单上的不同等级选项后,再点击开始按钮,蛇会以不同的速度运动。从1级到5级蛇的速度逐渐加大。所以等级设置正确,此游戏能够实现不同速度的运动。2)蛇颜色设置:当在游戏还没开始时,点击了菜单上的蛇颜色设置按钮中的不同颜色选项后,再点击开始按钮,会出现不同颜色的蛇。比如:点击白色,开始之后会出现一个运动着的白色蛇块。所以蛇的颜色设置正确,可以实现不同颜色的贪吃蛇。3)游戏帮助:打开此项菜单,包括游戏等级设置说明和蛇颜色设置说明两项。4)积分:当蛇吃了一块食物后,积分文本框内会相应的实现加10分的功能,并且当游戏结束之后会弹出一个对话框,显示游戏结束和总积分。4.2程序运行效果图 游戏方面:游戏设置:1)等级设置:2)蛇颜色设置:3)积分:5.实验总结通过这次试验,让我学到很多这个学期没有接触过的很多知识,完成一个贪吃蛇的项目;第一步就是先理清思路,设计主界面,主界面是以一具封闭的 画布,并在画布的设计蛇体和食物。蛇头如果碰到墙或者与蛇身的某一部分碰到就会死亡;如果蛇头碰到食物,就会自动增加一节蛇身,并更改得分。想要写出好的程序,还是要有扎实的基础,这样遇到问题就不会一筹莫展来。在编程时我们要有想象力,不要拘泥于现有的贪吃蛇游戏,而是要把自己想到的再加上所学的知识,遇到问题不能怕,而是要专心找出问题的原因,再回来看看书本的知识,不懂的还可以问问老师。编程过程还要养成良好的编程习惯,这样不仅自己能够很好看懂自己的代码,也让人家容易看懂自己的代码,而不至于代码知识自己会看,出来问题只有自己会解决而其他人都不会解决;遇到问题时要考虑最简单的解决方案,只有简单的方案不能满足要求时再考虑复杂的方案。最主要编程还是要多与人沟通,不会的不能立即问别人,但是一段时间后解决不了时还是应该向别人请教请教,“三人行必有我师”正是这个意思。通过这次实验,我深刻地体会到了面向对象与面向过程的区别。程序在最初设计时由于面向对象的思想不够成熟,导致在最后想要增加一些新的功能时,出现了一些麻烦,6.参考文献Vsiual C#.NET程序设计教案 清华大学出版社。邱锦伦附录A:主要源程序1)snakeBlock类: class snakeBlock/蛇块信息 private Color _color;/颜色 private int _size;/大小 private Point _point;/坐标 public snakeBlock(Color color, int size, Point p) this._color = color; this._size = size; this._point = p; public Point Point/属性 get return this._point; /绘制自身到画板 public virtual void Paint(Graphics g) SolidBrush sb = new SolidBrush(_color); lock (g) try g.FillRectangle(sb, this.Point.X * this._size, this.Point.Y * this._size, this._size - 1, this._size - 1); catch 2)snakeMod类: 变量设置: private int _width = 20; /宽度 private int _height = 20; /高度 public Color _bgColor; /背景色 private Graphics _gpPalette; /画布 private ArrayList _blocks; /蛇块列表 private Direction _direction ; /前进方向 public Timer timerBlock; /更新器 private int _level = 1; /游戏等级 public int le get return _level; set _level = value; private snakeBlock _food; /当前食物 private int _size = 20; /单位大小 private bool _isGameOver; private int _speed = new int 800, 450, 400, 350,150,250,200,100, 50 ;/游戏速度 构造函数:public snakeMode(int width, int height, int size,Color bgColor, Graphics g, int lvl) / 构造函数 this._width = width; this._height = height; this._bgColor = bgColor; this._gpPalette = g; this._size = size; /this.color = color; this._level = lvl; this._blocks = new ArrayList(); this._blocks.Insert(0, (new snakeBlock(Color.Blue, this._size, new Point(width / 2, height / 2); this._direction = Direction.Right; Start()函数:public void Start() this._food = GetFood();/生成一个食物 timerBlock = new System.Timers.Timer(_speedthis._level); /timerBlock = new System.Timers.Timer(se); timerBlock.Elapsed += new System.Timers.ElapsedEventHandler(OnBlockTimedEvent); timerBlock.AutoReset = true; timerBlock.Start(); 定时更新:private void OnBlockTimedEvent(object source, ElapsedEventArgs e)/定时更新 this.Move(); if (this.CheckDead() this.timerBlock.Stop(); /停止引发事件 this.timerBlock.Dispose(); /释放资源 int score=(this._blocks.Count-1)*10; System.Windows.Forms.MessageBox.Show(score: + score, Game Over!); 检查游戏是否结束:private bool CheckDead() /检查游戏是否结束 snakeBlock head = (snakeBlock)(this._blocks0);/超出画布范围 if (head.Point.X = 0 | head.Point.Y = 0 | head.Point.X = this._width +1| head.Point.Y = this._height+1) return true; for (int i = 1; i this._blocks.Count; i+) snakeBlock b = (snakeBlock)this._blocksi;/是否头尾相接 if (head.Point.X = b.Point.X & head.Point.Y = b.Point.Y) this._isGameOver = true; return true; this._isGameOver = false; return false; 生成下一个食物,也就是下一节蛇:private snakeBlock GetFood() / private snakeBlock GetFood() /生成下一个食物,也就是下一节蛇块 snakeBlock food = null; Random r = new Random(); bool redo = false; while (true) redo = false; int x = r.Next(this._width); int y = r.Next(this._height); for (int i = 0; i this._blocks.Count; i+) snakeBlock b = (snakeBlock)(this._blocksi); if (b.Point.X = x & b.Point.Y = y) redo = true; if (redo = false) food = new snakeBlock(Color.Gold, this._size, new Point(x, y); break; return food; 蛇体移动: private void Move() /蛇体移动 Point p = new Point(); /下一个位置 snakeBlock head = (snakeBlock)(this._blocks0); if (this._direction = Direction.Up) p = new Point(head.Point.X, head.Point.Y - 1); else if (this._direction = Direction.Down) p = new Point(head.Point.X, head.Point.Y + 1); else if (this._direction = Direction.Left) p = new Point(head.Point.X - 1, head.Point.Y); else p = new Point(head.Point.X + 1, head.Point.Y); /生成新坐标,将成为蛇头 snakeBlock b = new snakeBlock(Color.Red, this._size, p);/如果下一个坐标不是当前食物坐标,那么从蛇块信息列表中删除最后一个蛇块 if (this._food.Point != p) this._blocks.RemoveAt(this._blocks.Count - 1); /如果下一个坐标和食物坐标重合,那么就生成一个新食物 else this._food = this.GetFood(); /把下一个坐标插入到蛇块信息列表的第一个,使其成为蛇头 fen += 10; this._blocks.Insert(0, b); / 将元素插入指定索引处 this.PaintPalette(this._gpPalette); 更新画板: public void PaintPalette(Graphics gp) /更新画板 gp.Clear(this._bgColor); /清除整个绘图面并以指定背景色填充 this._food.Paint(gp); foreach (snakeBlock b in this._blocks) b.Paint(gp); 方向设置:enum Direction /枚举四个方向 Left, Right, Up, Downpublic Direction Direction get return this._direction; set this._direction = value ; Form1类:重新绘制: private void pictureBox1_Paint(object sender, PaintEventArgs e) if ( p!= null) p.PaintPalette(e.Graphics); 键盘响应的重写函数:protected override bool ProcessDialogKey(Keys keyData) if (keyData = Keys.Up | keyData = Keys.Down | keyData = Keys.Left | keyData = Keys.Right) return false; else return base.ProcessDialogKey(keyData); 键盘响应: private void Form1_KeyDown(object sender, KeyEventArgs e) if (e.KeyCode = Keys.D | e.KeyCode = Keys.Right )& p.Direction != Direction.Left) p.Direction = Direction.Right; textBox1.Text = p.fen.ToString(); return; if (e.KeyCode = Keys.W | e.KeyCode = Keys.Up) & p.Direction != Direction.Down) p.Direction = Direction.Up; textBox1.Text = p.fen.ToString(); return; if (e.KeyCode = Keys.S | e.KeyCode = Keys.Down) & p.Direction != Direction.Up) p.Direction = Direction.Down; textBox1.Text = p.fen.ToString(); return; if (e.KeyCode = Keys.A | e.KeyCode = Keys.Left) & p.Direction != Direction.Right) p.Direction = Direction.Left; textBox1.Text = p.fen.ToString(); return; 开始事件:private void button1_Click(object sender, EventArgs e) /定义画布长,宽,以及每个蛇块的大小 int width, height, size; width = height =
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 加速新质生产力发展的机遇和挑战
- 2025四川眉山仁寿县彰加镇人民政府招募见习人员2人考试笔试试卷【附答案】
- 河北秦皇岛市市直机关遴选公务员考试真题2024
- 2024年湖南省体育局下属事业单位考试真题
- 河南汇融数字科技有限公司招聘笔试题库2025
- 2025年会计师事务所劳动合同范本
- 2025年北京临时工劳动合同
- 2025年员工薪资调整与劳动合同协商
- 2025法律合同样例学校兼职教师聘用协议书
- 《2025年度一次性采购合同》
- DB3502∕T 090-2022 居家养老紧急事件应急助援规范
- 腰椎间盘突出症护理查房课件
- 2024口腔医学专业考核标准
- 大型群众性活动安全许可申请表
- 小学数学人教版-六年级上-第一单元-分数乘法-教材分析
- 百融云创风险决策引擎V5产品操作手册
- DL∕T 1281-2013 燃煤电厂固体废物贮存处置场污染控制技术规范
- DZ∕T 0033-2020 固体矿产地质勘查报告编写规范(正式版)
- 思念混声合唱简谱
- 家庭健康指导员培训方案及流程
- 贷款的培训课件
评论
0/150
提交评论