C#贪吃蛇游戏实现分析

2019-12-30 17:47:12于丽

代码3:


using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace EngorgeSerpent
{
 /// <summary>
 /// 蛇
 /// </summary>
 class Serpent
 {
 private List<Node> serpentList = new List<Node>();
 private Direction direction = Direction.Right;//运动方向
 private int maxCount = 15;
 private int minCount = 5;
 private System.Windows.Forms.Control MapPanel;
 Graphics g;
 /// <summary>
 /// 设置蛇长度数据
 /// </summary>
 /// <param name="maxLength">最大长度</param>
 /// <param name="minLength">最小长度</param>
 public Serpent(int maxLength, int minLength, System.Windows.Forms.Control c)
 {
  maxCount = maxLength;
  minCount = minLength;
  MapPanel = c;
  g = MapPanel.CreateGraphics();
 }

 /// <summary>
 /// 初始化蛇
 /// </summary>
 public void InitializeSerpent()
 {
  SolidBrush brush = null;
  RectangleF[] rects = new RectangleF[minCount];
  for (int i = 1; i < minCount; i++)
  {
  Node indexnode = new Node(i, 1);
  indexnode.SetSerpent(true);//设置蛇颜色
  serpentList.Insert(0, indexnode);
  if (brush == null)
  {
   brush = new SolidBrush(indexnode.SerpentColor);
  }
  rects[i] = new RectangleF(indexnode.X * indexnode.Width, indexnode.Y * indexnode.Width, indexnode.Width, indexnode.Width);
  }
  g.FillRectangles(brush, rects);
 }



 /// <summary>
 /// 插入一个
 /// </summary>
 /// <param name="node"></param>
 public void InsertNode(Node node)
 {
  serpentList.Insert(0, node);
  node.SetSerpent(true);
  SolidBrush brush = new SolidBrush(node.SerpentColor);
  RectangleF rect = new RectangleF(node.X * node.Width, node.Y * node.Width, node.Width, node.Width);
  g.FillRectangle(brush, rect);
 }

 /// <summary>
 /// 移除尾巴
 /// </summary>
 /// <param name="node"></param>
 public void RemoveNode()
 {
  Node node = serpentList[serpentList.Count - 1];
  serpentList.Remove(node);
  node.SetSerpent(false);
  SolidBrush brush = new SolidBrush(node.BgColor);
  RectangleF rect = new RectangleF(node.X * node.Width, node.Y * node.Width, node.Width, node.Width);
  g.FillRectangle(brush, rect);
 }

 /// <summary>
 /// 获取蛇头
 /// </summary>
 /// <returns>蛇头方格</returns>
 public Node GetSerpentHead()
 {
  return serpentList[0];
 }

 /// <summary>
 /// 蛇是否最长
 /// </summary>
 /// <returns></returns>
 public bool IsMax()
 {
  if (serpentList.Count == maxCount)
  return true;
  else
  return false;
 }

 /// <summary>
 /// 蛇运动方向
 /// </summary>
 public Direction Direction
 {
  get { return direction; }
  set { direction = value; }
 }

 }
 /// <summary>
 /// 运动方向
 /// </summary>
 public enum Direction
 {
 Left,
 Up,
 Right,
 Down
 }
}

代码4:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace EngorgeSerpent
{
 public partial class MainForm : Form
 {
 public MainForm()
 {
  InitializeComponent();

 }
 List<List<Node>> maplist = new List<List<Node>>();
 Map map;
 Serpent serpent;
 Graphics g;
 int level = 1;
 /// <summary>
 /// 运行线程
 /// </summary>
 Thread Work_Thread = null;
 /// <summary>
 /// 运行线程监控值
 /// </summary>
 bool IsWork = false;
 int sleepTime = 1000;
 int thissleeptime;

 private void MainForm_Load(object sender, EventArgs e)
 {
  g = this.panel1.CreateGraphics();
  map = new Map(40, 30, this.panel1);//这里可以对画布进行下大小设置 此处偷懒省略 
  LoadMapList();//加载障碍物列表  
 }

 /// <summary>
 /// 默认将地图设置为30*40
 /// </summary>
 private void SetMap()
 {
  map.ResetMap();
  g.Clear(map.BgColor);
  map.SetBorder();//设置边界
  List<Node> hiderList = GetHider();//获取障碍物列表
  map.SetHinder(hiderList);//设置障碍物
  SetSerpent();//初始化蛇 
 }

 /// <summary>
 /// 设置蛇
 /// </summary>
 private void SetSerpent()
 {
  serpent = new Serpent(15, 5, this.panel1);
  serpent.InitializeSerpent();//初始化蛇
 }

 /// <summary>
 /// 获取地图障碍物列表 以增加不同级别难度
 /// </summary>
 private void LoadMapList()
 {
  //目前分为5个级别
  //第一级别
  List<Node> hiderList1 = new List<Node>();
  for (int i = 15; i < 25; i++)
  {
  hiderList1.Add(map.GetNode(i, 15));
  hiderList1.Add(map.GetNode(15, i));
  }
  maplist.Add(hiderList1);

  //第二级别
  List<Node> hiderList2 = new List<Node>();
  for (int i = 7; i < 25; i++)
  {
  hiderList2.Add(map.GetNode(i, 15));
  hiderList2.Add(map.GetNode(15, i));
  }
  maplist.Add(hiderList2);

  //第三级别
  List<Node> hiderList3 = new List<Node>();
  for (int i = 7; i < 25; i++)
  {
  hiderList3.Add(map.GetNode(i, 15));
  hiderList3.Add(map.GetNode(15, i));
  hiderList3.Add(map.GetNode(i, 25));
  }
  maplist.Add(hiderList3);

  //第四级别
  List<Node> hiderList4 = new List<Node>();
  for (int i = 7; i < 25; i++)
  {
  hiderList4.Add(map.GetNode(i, 25));
  hiderList4.Add(map.GetNode(i, 15));
  hiderList4.Add(map.GetNode(15, i));
  hiderList4.Add(map.GetNode(i, 7));
  }
  maplist.Add(hiderList4);

  //第五级别
  List<Node> hiderList5 = new List<Node>();
  for (int i = 7; i < 25; i++)
  {
  hiderList5.Add(map.GetNode(i, 25));
  hiderList5.Add(map.GetNode(i, 15));
  hiderList5.Add(map.GetNode(15, i));
  hiderList5.Add(map.GetNode(i, 7));
  hiderList5.Add(map.GetNode(i, 35));
  }
  for (int i = 12; i < 20; i++)
  {
  hiderList5.Add(map.GetNode(7, i));
  hiderList5.Add(map.GetNode(25, i));
  }
  maplist.Add(hiderList5);
 }

 /// <summary>
 /// 获取障碍物列表
 /// </summary>
 /// <returns></returns>
 private List<Node> GetHider()
 {
  //这里可以添加多个地图,当级别改变时需要重新加载
  return maplist[level - 1];
 }

 /// <summary>
 /// 重置地图
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void btnResetMap_Click(object sender, EventArgs e)
 {
  IsWork = false;
  btnStop.Enabled = false;
  button3.Enabled = false;
  button2.Enabled = true;
  //map.ResetMap();
  SetMap();
 }

 /// <summary>
 /// 运行
 /// </summary>
 private void Work()
 {
  map.SetFood();//设置食物
  while (IsWork)
  {
  Node node_index;
  Node serpentHead = serpent.GetSerpentHead();
  switch (serpent.Direction)
  {
   case Direction.Left:
   node_index = map.GetNode(serpentHead.X - 1, serpentHead.Y);
   break;
   case Direction.Right:
   node_index = map.GetNode(serpentHead.X + 1, serpentHead.Y);
   break;
   case Direction.Up:
   node_index = map.GetNode(serpentHead.X, serpentHead.Y - 1); break;
   default:
   node_index = map.GetNode(serpentHead.X, serpentHead.Y + 1);
   break;
  }
  SerpentState index_move = SerpentMove(node_index);
  if (index_move == SerpentState.Error)//游戏结束
  {
   IsWork = false;
   //map.ResetMap();
   MessageBox.Show("游戏结束!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
   sleepTime = 1000;
   level = 1;
   thissleeptime = sleepTime;
   lblLevel.BeginInvoke(new MethodInvoker(delegate()
   {
   btnStop.Enabled = false;
   button3.Enabled = false;
   button2.Enabled = true;
   lblLevel.Text = "1";
   lblCount.Text = "5";
   }));
  }
  else if (index_move == SerpentState.NextLevel)
  {
   IsWork = false;
   this.lblCount.BeginInvoke(new MethodInvoker(delegate()
   {
   level += 1;
   lblLevel.Text = level.ToString();
   lblCount.Text = "5";
   }));
   sleepTime = sleepTime / 2;
   thissleeptime = sleepTime;
   SetMap();//重置地图
  }
  else
  {

   Thread.Sleep(thissleeptime);
  }
  }
  map.ResetMap();
 }

 /// <summary>
 /// 开始
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void button2_Click(object sender, EventArgs e)
 {
  IsWork = false;
  btnStop.Enabled = false;
  button3.Enabled = false;
  button2.Enabled = true;
  //map.ResetMap();
  SetMap();
  thissleeptime = sleepTime;
  this.panel1.Focus();
  IsWork = true;
  this.btnStop.Enabled = true;
  this.button3.Enabled = true;
  button2.Enabled = false;
  Work_Thread = new Thread(new ThreadStart(Work));
  Work_Thread.IsBackground = true;
  Work_Thread.Start();
 }

 private void MainForm_KeyDown(object sender, KeyEventArgs e)
 {

  if (e.KeyCode == Keys.Right)
  {
  if (serpent.Direction != Direction.Left)
   serpent.Direction = Direction.Right;
  }
  else if (e.KeyCode == Keys.Left)
  {
  if (serpent.Direction != Direction.Right)
   serpent.Direction = Direction.Left;
  }
  else if (e.KeyCode == Keys.Up)
  {
  if (serpent.Direction != Direction.Down)
   serpent.Direction = Direction.Up;
  }
  else if (e.KeyCode == Keys.Down)
  {
  if (serpent.Direction != Direction.Up)
   serpent.Direction = Direction.Down;
  }
  else if (e.KeyCode == Keys.Space)
  {
  thissleeptime = sleepTime / 2;
  }
  else if (e.KeyCode == Keys.Escape)
  {
  if (IsWork)
  {
   this.button3.Text = "继续";
   IsWork = false;
  }

  }
 }

 /// <summary>
 /// 暂停
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void button3_Click(object sender, EventArgs e)
 {
  if (!IsWork)
  {
  this.button3.Text = "暂停";
  IsWork = true;
  Work_Thread = new Thread(new ThreadStart(Work));
  Work_Thread.IsBackground = true;
  Work_Thread.Start();
  }
  else
  {
  this.button3.Text = "继续";
  IsWork = false;
  }
 }
 /// <summary>
 /// 退出
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void button4_Click(object sender, EventArgs e)
 {
  this.Close();
 }

 private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
 {
  IsWork = false;
  Application.Exit();
  System.Diagnostics.Process.GetCurrentProcess().Kill();
 }



 private void btnStop_Click(object sender, EventArgs e)
 {
  // map.ResetMap();
  btnStop.Enabled = false;
  button3.Enabled = false;
  button2.Enabled = true;
  IsWork = false;
  Work_Thread.Abort();
  SetMap();
 }

 /// <summary>
 /// 移动
 /// </summary>
 /// <param name="node">将要移动到的节点</param>
 /// <returns>返回状态</returns>
 private SerpentState SerpentMove(Node node)
 {
  if (!node.IsPass)
  {
  return SerpentState.Error;
  }
  serpent.InsertNode(node);
  if (!node.IsFood)
  {
  //不是食物,则移除最后一个节点
  serpent.RemoveNode();
  }
  else
  {
  lblCount.BeginInvoke(new MethodInvoker(delegate()
  {
   this.lblCount.Text = (Convert.ToInt32(this.lblCount.Text.Trim()) + 1).ToString();
  }));
  map.SetFood();//设置食物
  }

  if (serpent.IsMax())
  {
  return SerpentState.NextLevel;
  }
  return SerpentState.Moving;
 }

 private void MainForm_KeyUp(object sender, KeyEventArgs e)
 {
  if (e.KeyCode == Keys.Space)
  {
  thissleeptime = sleepTime;
  }
 }

 private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
 {
  int index = 1;
  int index_count = Convert.ToInt32(comboBox1.Text);
  for (int i = 1; i < index_count; i++)
  {
  index = index * 2;
  }
  level = index_count;
  sleepTime = 1000 / index;
  thissleeptime = sleepTime;
  btnStop.Enabled = false;
  button3.Enabled = false;
  button2.Enabled = true;
  IsWork = false;

  SetMap();
  lblCount.Text = "5";
  lblLevel.Text = index_count.ToString();
  serpent.Direction = Direction.Right;

 }

 private void checkBox1_Click(object sender, EventArgs e)
 {
  comboBox1.Enabled = this.checkBox1.Checked;
 }

 }
 public enum SerpentState
 {
 Moving,
 NextLevel,
 Error
 }
}