初学C#:贪吃蛇
2016-08-18 21:19
134 查看
最近准备开始学学C#,因为有着C和C++的基础,C#语法和面对对象方面我就大概浏览了一下,然后就开始看窗体部分。书上的窗体部分只讲了控件。。。。于是准备从小游戏写起练习一下
昨天按着网上的代码抄了一遍= =!终于搞懂了这个游戏。今天下午又看了一个代码,于是乎准备自己写啦。
好了,下面说我写的代码
首先先说界面!
添加的控件有两个label(一个也是够的),一个pictureBox,两个button控件。
每个小方格大小为15*15,共有30*30个方格。
于是开始设计窗体和控件的大小和位置
昨天看的网上的代码,直接在窗体上画蛇和食物,运行的时候窗体会一闪一闪的。这次用了pictureBox来画图,终于不再闪了。
运行的时候在pictureBox里画30*30个小方格、蛇、食物,一会再贴代码。
根据分析,我写(抄)了三个对象,蛇,食物,”游戏”。
先说蛇这个对象,它的属性有什么? 长度,身体每个点的位置(用list储存),速度
4000
,行进方向,头部的位置,就这些喽。
蛇的身体的点的范围是(0-30,0-30)
首先我们先把蛇的行进方向枚举出来,就是这样
然后对象蛇的代码:
然后是食物这个对象,就一个属性,位置,不说了
然后是 “游戏这个对象”
每一个”游戏”的实例代表一局新的游戏,它就只有两个属性,蛇和食物
然后说它的方法
蛇吃掉食物后,肯定要更新一个新的食物,所以写了CreateFood方法,当然判断蛇能不能吃到食物我也写了一个方法。接下来,写一个判断有木有Game Over的方法。就这样了。
好了,三个对象全部搞定之后,就开始写游戏进行时的部分了
绘图部分全部写在了pictureBox的paint方法里
游戏进行时,计时器根据蛇的速度来发送Tick事件,
在每次Tick事件中,
蛇行进一步,然后判断是否Game OVer,判断是否吃到食物,更新分数,接着pictureBox重绘
接着写响应键盘事件,原来写的是方向键来控制方向,结果按下方向键之后,根本不响应,焦点在两个button控件间切来切去,只好换成了wasd= =!
剩下两个button的点击事件我就不说了,直接上代码
然后就没了。。。表达能力不强,只能写到这里了。刚开始学,肯定有不足的地方或者Bug,欢迎指正= =
欢迎加我QQ一起学习1594205849
昨天按着网上的代码抄了一遍= =!终于搞懂了这个游戏。今天下午又看了一个代码,于是乎准备自己写啦。
好了,下面说我写的代码
首先先说界面!
添加的控件有两个label(一个也是够的),一个pictureBox,两个button控件。
每个小方格大小为15*15,共有30*30个方格。
于是开始设计窗体和控件的大小和位置
private void Form1_Load(object sender, EventArgs e) { // 设计pictureBox1 pictureBox1.Size = new Size(450, 450); pictureBox1.BackColor = Color.Red; pictureBox1.Location = new Point(0, 0); //设计窗体 this.ClientSize = new Size(600, 450); this.MaximizeBox = false; this.MinimizeBox = false; this.FormBorderStyle = FormBorderStyle.FixedDialog; // 锁定窗体大小 this.KeyPreview = true; //接收键盘消息 //设计label label1.Location = new Point(500, 100); label2.Location = new Point(550, 100); label2.Text = " "; //设计button button1.Location = new Point(475, 200); button2.Location = new Point(475, 300); button1.Size = button2.Size = new Size(100, 50); button1.Text = "开始"; button2.Text = "新的游戏"; // 计时器 timer1.Enabled = true; timer1.Stop(); sign = 0; }
昨天看的网上的代码,直接在窗体上画蛇和食物,运行的时候窗体会一闪一闪的。这次用了pictureBox来画图,终于不再闪了。
运行的时候在pictureBox里画30*30个小方格、蛇、食物,一会再贴代码。
根据分析,我写(抄)了三个对象,蛇,食物,”游戏”。
先说蛇这个对象,它的属性有什么? 长度,身体每个点的位置(用list储存),速度
4000
,行进方向,头部的位置,就这些喽。
蛇的身体的点的范围是(0-30,0-30)
首先我们先把蛇的行进方向枚举出来,就是这样
enum SnakeDirection { Up, Down, Left, Right }
然后对象蛇的代码:
class Snake { private int length = 0; //长度 private List<Point> bodisLocation; //身体 private int speed; //速度 private SnakeDirection snakeDirection = SnakeDirection.Right; //方向 private Point HeadPoint; //头部 //构造函数,参数为速度,初始长度为5,方向为右 public Snake(int speed) { bodisLocation = new List<Point>(); this.speed = speed; this.length = 5; for (int i = 4; i >= 0; i--) { Point pp = new Point(i, 0); bodisLocation.Add(pp); } HeadPoint = new Point(4, 0); } //方法,向 行进方向 行进一步 public void SnakeRun() { int size = bodisLocation.Count; for (int i = size - 1; i > 0; i--)// 行进一个单位后,除头部外,每节身体的位置是未行进前该节身体的前一节的位置 { bodisLocation[i] = bodisLocation[i - 1]; } Point head = bodisLocation[0]; switch (snakeDirection)//根据行进方向得到新的头部的位置 { case SnakeDirection.Down: head = new Point(head.X, head.Y + 1); break; case SnakeDirection.Up: head = new Point(head.X, head.Y - 1); break; case SnakeDirection.Right: head = new Point(head.X + 1, head.Y); break; case SnakeDirection.Left: head = new Point(head.X - 1, head.Y); break; } bodisLocation[0] = head; //更新头部 length = bodisLocation.Count; //更新长度 HeadPoint = bodisLocation[0]; } //属性 public SnakeDirection SnakeDirection //方向 { get { return snakeDirection; } set { snakeDirection = value; } } public int Speed //速度 { get { return speed; } set { speed = value; } } public int Length // 长度 { get { return length; } set { length = value; } } public List<Point> BodisLocation //身体 { get { return bodisLocation; } set { bodisLocation = value; } } public Point Head //头部 { get { return HeadPoint; } } }
然后是食物这个对象,就一个属性,位置,不说了
class Food { private Point Position; public Food() { Position = new Point(0, 0); } public Point location { get { return Position; } set { Position = value; } } }
然后是 “游戏这个对象”
每一个”游戏”的实例代表一局新的游戏,它就只有两个属性,蛇和食物
然后说它的方法
蛇吃掉食物后,肯定要更新一个新的食物,所以写了CreateFood方法,当然判断蛇能不能吃到食物我也写了一个方法。接下来,写一个判断有木有Game Over的方法。就这样了。
class OneGame { public Snake snake; public Food food; public OneGame() { snake = new Snake(150); // 蛇的初始速度定为150 food = new Food(); CreateFood(); } //方法,制造一个食物 public void CreateFood() { Random r = new Random(); int sign = 0; while(sign==0) // 直到 食物的位置不在蛇身体位置上 结束循环 { food.location = new Point(r.Next(30), r.Next(30)); foreach(Point pp in snake.BodisLocation) { if(food.location==pp) break; } sign = 1; } } //方法,蛇吃食物 public void EatFood() { if(snake.BodisLocation[0]==food.location) { snake.BodisLocation.Add(food.location); // 把食物的位置添加进身体里就行 CreateFood(); } } //方法,判断是否Game Over; public bool IsGameOver() { for (int i = 1; i < snake.BodisLocation.Count; i++) //遍历身体,如果头部和身体的位置相同,则游戏结束 if (snake.BodisLocation[0] == snake.BodisLocation[i]) return true; Point pp = snake.Head; if (pp.X < 0 || pp.X >= 30 || pp.Y < 0 || pp.Y >= 30) // 超出边界则游戏结束 return true; return false; } }
好了,三个对象全部搞定之后,就开始写游戏进行时的部分了
绘图部分全部写在了pictureBox的paint方法里
private void pictureBox1_Paint(object sender, PaintEventArgs e) { int i, j; Graphics g = e.Graphics; SolidBrush mybrush = new SolidBrush(Color.Yellow); for (i = 0; i < 30; i++) // 画出背景 for (j = 0; j < 30; j++) { Point Start = new Point(i * 15, j * 15); Size size = new Size(15, 15); g.FillEllipse(mybrush, new Rectangle(Start, size)); } foreach(Point pp in myGame.snake.BodisLocation) // 画出蛇 { i = pp.X; j = pp.Y; mybrush = new SolidBrush(Color.Black); Point Start = new Point(i * 15, j * 15); Size size = new Size(15, 15); g.FillEllipse(mybrush, new Rectangle(Start, size)); } mybrush = new SolidBrush(Color.White); //画出食物 i = myGame.food.location.X; j = myGame.food.location.Y; mybrush = new SolidBrush(Color.White); Point sstart = new Point(i * 15, j * 15); Size ssize = new Size(15, 15); g.FillEllipse(mybrush, new Rectangle(sstart, ssize)); }
游戏进行时,计时器根据蛇的速度来发送Tick事件,
在每次Tick事件中,
蛇行进一步,然后判断是否Game OVer,判断是否吃到食物,更新分数,接着pictureBox重绘
private void timer1_Tick(object sender, EventArgs e) { myGame.snake.Speed =200- myGame.snake.Length*2;//根据长度增加速度 timer1.Interval = myGame.snake.Speed; myGame.snake.SnakeRun(); // 蛇行进一步 if(myGame.IsGameOver()) //判断是否game over { timer1.Stop(); MessageBox.Show("Game Over!"); myGame = new OneGame(); button1.Text = "开始"; sign = 0; } myGame.EatFood(); // 能否吃到食物 label2.Text = myGame.snake.Length.ToString(); /更新分数 pictureBox1.Invalidate(); // pictureBox重绘 }
接着写响应键盘事件,原来写的是方向键来控制方向,结果按下方向键之后,根本不响应,焦点在两个button控件间切来切去,只好换成了wasd= =!
private void Form1_KeyDown(object sender, KeyEventArgs e) { if (e. c85b KeyCode == Keys.W && myGame.snake.SnakeDirection != SnakeDirection.Down) myGame.snake.SnakeDirection = SnakeDirection.Up; else if (e.KeyCode == Keys.S && myGame.snake.SnakeDirection != SnakeDirection.Up) myGame.snake.SnakeDirection = SnakeDirection.Down; else if (e.KeyCode == Keys.A && myGame.snake.SnakeDirection != SnakeDirection.Right) myGame.snake.SnakeDirection = SnakeDirection.Left; else if (e.KeyCode == Keys.D && myGame.snake.SnakeDirection != SnakeDirection.Left) myGame.snake.SnakeDirection = SnakeDirection.Right; }
剩下两个button的点击事件我就不说了,直接上代码
private void button1_Click(object sender, EventArgs e)// 开始 and 暂停 按钮 { if (sign == 0) // 按下了 开始 { sign = 1; timer1.Start(); button1.Text = "暂停"; } else // 按下了 暂停 { sign = 0; timer1.Stop(); button1.Text = "开始"; } } private void button2_Click(object sender, EventArgs e) //按下 新游戏 按钮 { timer1.Stop(); //计时器停止 myGame = new OneGame(); // 重新 sign = 0; button1.Text = "开始"; pictureBox1.Invalidate(); }
然后就没了。。。表达能力不强,只能写到这里了。刚开始学,肯定有不足的地方或者Bug,欢迎指正= =
欢迎加我QQ一起学习1594205849
相关文章推荐
- 浅谈贪吃蛇的设计及算法
- C语言-贪吃蛇设计思路——从不知所措到逐渐清晰
- 简单字符游戏——贪吃蛇
- 字符版本贪吃蛇游戏设计及算法
- 字符游戏贪吃蛇的尝试
- 贪吃蛇设计
- 贪吃蛇游戏其他方法
- 字符游戏-贪吃蛇
- 智能贪吃蛇的实现方法介绍
- javascript_贪吃蛇_面向过程的写法
- 如何做一个贪吃蛇的小游戏
- 使用pygame模块编写贪吃蛇的实例讲解
- 一个小白写的控制台的贪吃蛇
- 贪吃蛇 - 完整版
- c语言 贪吃蛇
- 从零开始学 Web 之 JavaScript 高级(一)原型,贪吃蛇案例
- Excel下实现贪吃蛇小游戏
- C-贪吃蛇-基于字符屏幕80*25 turboc 2.0
- 贪吃蛇
- javascript 实现的多浏览器支持的贪吃蛇webgame