前几天有个学生做了一个贪吃蛇的小游戏,他原来考虑使用线程实现,由于课堂上没有给他们讲过线程,所以指导他改用了定时器来实现了这个小游戏。
游戏使用C#语言描述实现,里面主要用到了以下知识点:
1、 循环
2、 定时器
3、 动态生成控件
4、 逻辑控制处理
5、 游戏规则模拟处理
游戏时的截图:
后面附具体源码
部分具体实现代码如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Threading; namespace Snake { enum DIR { L, R, U, D }//L, R, U, D,分别代表左移、右移、上移、下移 public partial class Snake : Form { int level = 1; int xold, yold;//记录蛇头的初始位置 DIR direction = DIR.R;//默认移动方向 //Keys dir = Keys.Right;//默认移动方向 int snakeBody = 4;//蛇身长度 int snakeX;//蛇身初始的x轴坐标 int snakeY;//蛇身初始的y轴坐标 Label lblFood;//生成的蛇食 Label lbl; List<Label> list = new List<Label>(); public Snake() { InitializeComponent(); } private void Snake_Load(object sender, EventArgs e) { lblSnakeHead.BackColor = Color.FromArgb(0, 255, 0); AddBody(); GenerrationFood(); timer1.Enabled = true; timer1.Start(); } /// <summary> /// 键盘按键按下事件,判断获取蛇头的方向信息 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Snake_KeyDown(object sender, KeyEventArgs e) { switch (e.KeyData) { case Keys.A: direction = DIR.L; break; case Keys.Left: direction = DIR.L; break; case Keys.D: direction = DIR.R; break; case Keys.Right: direction = DIR.R; break; case Keys.W: direction = DIR.U; break; case Keys.Up: direction = DIR.U; break; case Keys.S: direction = DIR.D; break; case Keys.Down: direction = DIR.D; break; default: break; } } /// <summary> /// 生成蛇食 /// </summary> private void GenerrationFood() { lblFood = new Label(); lblFood.BackColor = Color.DeepPink; lblFood.Size = new System.Drawing.Size(10, 10); lblFood.BorderStyle = BorderStyle.FixedSingle; Random random = new Random(); int x = random.Next(0, 79); int y = random.Next(0, 59); x = x * 10; y = y * 10; lblFood.Location = new System.Drawing.Point(x, y); this.Controls.Add(lblFood); } /// <summary> /// 生成蛇身 /// </summary> private void AddBody() { snakeX = lblSnakeHead.Left; snakeY = lblSnakeHead.Top; for (int i = 0; i < snakeBody; i++) { lbl = new Label(); lbl.Size = new System.Drawing.Size(10, 10); lbl.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; lbl.Location = new System.Drawing.Point(snakeX + 20 * i, snakeY); lbl.Name = i.ToString(); lbl.BackColor = Color.DarkMagenta; this.Controls.Add(lbl); list.Add(lbl); } } /// <summary> /// 通过蛇头来移动蛇身位置 /// </summary> private void MoveBody() { int x, y;//用来接收除蛇头外的其余lbl移动前的坐标 for (int i = 0; i < list.Count; i++) { x = list[i].Left; y = list[i].Top; list[i].Left = xold; list[i].Top = yold; xold = x; yold = y; } } /// <summary> /// 移动蛇头,根据方向来调整蛇头就位置 /// </summary> /// <returns>是否移动成功,即是否游戏触碰边界,游戏失败</returns> private bool MoveHead() { bool bFailed = false; xold = lblSnakeHead.Left; yold = lblSnakeHead.Top; switch (direction) { case DIR.U: lblSnakeHead.Top -= 10; snakeY -= 10; if (lblSnakeHead.Top <= 0) { bFailed = true; } break; case DIR.D: lblSnakeHead.Top += 10; snakeY += 10; if (lblSnakeHead.Top >= 600) { bFailed = true; } break; case DIR.L: lblSnakeHead.Left -= 10; snakeX -= 10; if (lblSnakeHead.Left <= 0) { bFailed = true; } break; case DIR.R: lblSnakeHead.Left += 10; snakeX += 10; if (lblSnakeHead.Left >= 800) { bFailed = true; } break; } return bFailed; } private void timer1_Tick(object sender, EventArgs e) { bool bFailed = MoveHead(); if (bFailed) { timer1.Enabled = false; timer1.Stop(); DialogResult choice = MessageBox.Show("您失败了,游戏结束。是否重新开始?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (choice == System.Windows.Forms.DialogResult.Yes) { //游戏失败后重新开始游戏,初始化游戏设置参数 this.Text = string.Format("贪吃蛇:第1关"); level = 1; snakeBody = 4; timer1.Interval = 200; direction = DIR.R; lblSnakeHead.Top = 220; lblSnakeHead.Left = 220; lblSnakeHead.BackColor = Color.FromArgb(0, 255, 0); foreach (Label lbl in list) { this.Controls.Remove(lbl); } list.Clear(); AddBody();//重新生成蛇身 //重新生成食物位置 Random random = new Random(); int x = random.Next(1, 77); int y = random.Next(1, 54); x = x * 10; y = y * 10; lblFood.Location = new System.Drawing.Point(x, y); timer1.Enabled = true; timer1.Start(); } } else { MoveBody();//移动身体 //判断是否吃到食物 if (lblSnakeHead.Location == this.lblFood.Location) { timer1.Enabled = false; timer1.Stop(); MessageBox.Show(string.Format("恭喜,你经过了第{0}关", level), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); timer1.Enabled = true; timer1.Start(); level++; this.Text = string.Format("贪吃蛇:第{0}关", level); snakeBody += 1; timer1.Interval -= 10; //过关时改变蛇头的颜色 if (level >= 21) { lblSnakeHead.BackColor = Color.FromArgb(255, 0, 0); } else { lblSnakeHead.BackColor = Color.FromArgb(150 + level * 5, 0, 0); } lblSnakeHead.Top = 220; lblSnakeHead.Left = 220; foreach (Label lbl in list) { this.Controls.Remove(lbl); } list.Clear(); AddBody();//蛇身增加后重新生成蛇身 //重新生成食物位置 Random random = new Random(); int x = random.Next(1, 79); int y = random.Next(1, 59); x = x * 10; y = y * 10; lblFood.Location = new System.Drawing.Point(x, y); } } } } }
实现的具体源码: