C#如何实现贪吃蛇游戏
这篇文章主要为大家展示了C#如何实现贪吃蛇游戏,内容简而易懂,希望大家可以学习一下,学习完之后肯定会有收获的,下面让小编带大家一起来看看吧。
成都创新互联公司主营巴州网站建设的网络公司,主营网站建设方案,成都App定制开发,巴州h5小程序开发搭建,巴州网站营销推广欢迎巴州等地区企业咨询
贪吃蛇分析
游戏规则:
1、蛇起始长度5,每吃一个食物增加1,最大15过关
2、蛇用蓝色表示,食物用绿色,障碍物用黑色
3、当蛇碰到自己、墙壁、障碍物则游戏失败
4、方向键控制蛇的移动方向,蛇不可反方向移动,如正在向上移动,不能马上向下,只能向左、右、上运动
5、每过关一次速度提升一次
大概思路:
1、地图用网格的形式表示,蛇由方格组成,保存在list中
2、1中提到了方格,方格保存的内容有,颜色,坐标,是否可以通过,是否是食物
3、向前移动一次,将前面方格添加进蛇列表中,将列表最后一个移除,若为前方格子为食物,则不移除最后一个
4、使用while死循环来做整个移动
5、空格键为加速键,通过修改while循环sleep时间来实现加速
包括了3个类一个主窗体,分别是Node(用来表示方格)、Map(用来表示地图)、Serpent(用来表示蛇),另外一个主窗体。下面依次把代码贴上,基本上每个方法都有注释
代码1:
using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace EngorgeSerpent { ////// 节点 /// class Node { #region 字段 private int x; private int y; private int width = 10; private bool isFood = false; private bool isPass = true;//是否可通过 private Color bgColor = Color.FromArgb(224, 224, 224); private Color foodColor = Color.Green; private Color hinderColor = Color.Black; private Color thisColor; private Color serpentColor = Color.Chocolate; #endregion ////// 设置食物参数 /// /// public void SetFood(bool _isFood) { IsFood = _isFood; if (_isFood) { ThisColor = FoodColor; } else { ThisColor = BgColor; } } ////// 设置障碍物参数 /// /// 是否为障碍物 public void SetHinder(bool _isHinder) { IsPass =! _isHinder; if (_isHinder) { ThisColor = HinderColor; } else { ThisColor = BgColor; } } ////// 设置蛇颜色 /// /// public void SetSerpent(bool _isSerpent) { IsPass = !_isSerpent; if (_isSerpent) { ThisColor = SerpentColor; } else { ThisColor = BgColor; } } #region 构造函数 public Node() { thisColor = bgColor; } ////// 有参构造方法 /// /// 相对x坐标 /// 相对y坐标 /// 边长 /// 是否是食物 /// 是否可通过 public Node(int _x, int _y, int _width, bool _isFood, bool _isPass) { thisColor = bgColor; X = _x; Y = _y; Width = _width; IsFood = _isFood; IsPass = _isPass; } ////// 有参构造方法 /// /// 相对x坐标 /// 相对y坐标 /// 边长 public Node(int _x, int _y, int _width) { X = _x; Y = _y; Width = _width; } ////// 有参构造方法 /// /// 相对x坐标 /// 相对y坐标 public Node(int _x, int _y) { X = _x; Y = _y; } #endregion #region 属性 ////// 蛇颜色 /// public Color SerpentColor { get { return serpentColor; } } ////// 背景色 /// public Color BgColor { get { return bgColor; } } ////// 食物颜色 /// public Color FoodColor { get { return foodColor; } } ////// 障碍物颜色 /// public Color HinderColor { get { return hinderColor; } } ////// 当前颜色 /// public Color ThisColor { get { return thisColor; } set { thisColor = value; } } ////// 获取或设置相对横坐标 /// public int X { get { return x; } set { x = value; } } ////// 获取或设置相对纵坐标 /// public int Y { get { return y; } set { y = value; } } ////// 获取或设置节点边长 /// public int Width { get { return width; } set { width = value; } } ////// 获取或设置是否为食物 /// public bool IsFood { get { return isFood; } set { isFood = value; } } ////// 获取或设置是否可以通过 /// public bool IsPass { get { return isPass; } set { isPass = value; } } #endregion } }
代码2:
using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace EngorgeSerpent { ////// 地图 /// class Map { ////// 节点数组 /// private List> _nodes; private int RowCount; private int ComsCount; private Color bgColor = Color.FromArgb(224, 224, 224); private System.Windows.Forms.Control MapPanel; Graphics g; ///
/// 地图背景色 和node中背景色一致 /// public Color BgColor { get { return bgColor; } } ////// 构造方法 /// /// 行数 /// 列数 public Map(int rows, int coms, System.Windows.Forms.Control c) { RowCount = rows; ComsCount = coms; MapPanel = c; g = c.CreateGraphics(); _nodes = new List>(); for (int i = 0; i < rows; i++)//行 { List
index = new List (); for (int j = 0; j < coms; j++) { Node node = new Node(j, i); index.Add(node); } _nodes.Add(index); } } /// /// 构造方法 /// /// 行数 /// 列数 /// 节点宽度 public Map(int rows, int coms, int width, System.Windows.Forms.Control c) { RowCount = rows; ComsCount = coms; MapPanel = c; g = c.CreateGraphics(); _nodes = new List>(); for (int i = 0; i < coms; i++)//行 { List
index = new List (); for (int j = 0; j < rows; j++) { Node node = new Node(j, i, width); index.Add(node); } _nodes.Add(index); } } /// /// 重新加载地图 /// public void ResetMap() { for (int i = 0; i < ComsCount; i++)//行 { for (int j = 0; j < RowCount; j++) { Node node = GetNode(i, j); node.IsPass = true; node.IsFood = false; } } } ////// 获得节点 /// /// /// ///public Node GetNode(int x, int y) { return _nodes[y][x]; } /// /// 设置食物 /// public void SetFood() { SolidBrush brush = null; int _x, _y; Random r = new Random(); while (true) { _x = r.Next(0, RowCount); _y = r.Next(0, ComsCount); if (_nodes[_x][_y].IsPass) { break; } } Node nodeindex = _nodes[_x][_y]; nodeindex.SetFood(true); brush = new SolidBrush(nodeindex.FoodColor); RectangleF[] rects = { new RectangleF(nodeindex.X * nodeindex.Width, nodeindex.Y * nodeindex.Width, nodeindex.Width, nodeindex.Width) }; g.FillRectangles(brush, rects); } ////// 设置障碍物 /// /// public void SetHinder(Listlist) { SolidBrush brush = null; RectangleF[] rects = new RectangleF[list.Count]; for (int i = 0; i < list.Count; i++) { Node _node = list[i]; _node.SetHinder(true); _node.IsPass = false; if (brush == null) { brush = new SolidBrush(_node.HinderColor); } RectangleF r = new RectangleF(_node.X * _node.Width, _node.Y * _node.Width, _node.Width, _node.Width); rects[i] = r; } g.FillRectangles(brush, rects); } /// /// 设置边界 /// public void SetBorder() { //通过计算得出边界的个数是2(x+y-2)个方格 SolidBrush brush = null; int borders = 2 * (ComsCount + RowCount - 2); RectangleF[] rects = new RectangleF[borders]; int indexcount = 0; //添加顶部方格进rects列表中 for (int i = 0; i < RowCount; i++) { Node _node = _nodes[i][0]; _node.SetHinder(true); if (brush == null) { brush = new SolidBrush(_node.HinderColor); } RectangleF r = new RectangleF(_node.X * _node.Width, _node.Y * _node.Width, _node.Width, _node.Width); rects[indexcount] = r; indexcount++; } //添加底部方格进rects列表中 for (int i = 0; i < RowCount; i++) { Node _node = _nodes[i][ComsCount - 1]; _node.SetHinder(true); RectangleF r = new RectangleF(_node.X * _node.Width, _node.Y * _node.Width, _node.Width, _node.Width); rects[indexcount] = r; indexcount++; } //添加左侧方格进列表,因为左侧最上面以及最下面的两个方格已经添加进去,这里不需要重复添加 for (int i = 1; i < ComsCount - 1; i++) { Node _node = _nodes[0][i]; _node.SetHinder(true); RectangleF r = new RectangleF(_node.X * _node.Width, _node.Y * _node.Width, _node.Width, _node.Width); rects[indexcount] = r; indexcount++; } //添加右侧方格进列表,因为右侧最上面以及最下面两个方格已经添加进去,这里不需要重复添加 for (int i = 1; i < ComsCount - 1; i++) { Node _node = _nodes[RowCount - 1][i]; _node.SetHinder(true); RectangleF r = new RectangleF(_node.X * _node.Width, _node.Y * _node.Width, _node.Width, _node.Width); rects[indexcount] = r; indexcount++; } g.FillRectangles(brush, rects); } } }
代码3:
using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace EngorgeSerpent { ////// 蛇 /// class Serpent { private ListserpentList = new List (); private Direction direction = Direction.Right;//运动方向 private int maxCount = 15; private int minCount = 5; private System.Windows.Forms.Control MapPanel; Graphics g; /// /// 设置蛇长度数据 /// /// 最大长度 /// 最小长度 public Serpent(int maxLength, int minLength, System.Windows.Forms.Control c) { maxCount = maxLength; minCount = minLength; MapPanel = c; g = MapPanel.CreateGraphics(); } ////// 初始化蛇 /// 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); } ////// 插入一个 /// /// 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); } ////// 移除尾巴 /// /// 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); } ////// 获取蛇头 /// ///蛇头方格 public Node GetSerpentHead() { return serpentList[0]; } ////// 蛇是否最长 /// ///public bool IsMax() { if (serpentList.Count == maxCount) return true; else return false; } /// /// 蛇运动方向 /// public Direction Direction { get { return direction; } set { direction = value; } } } ////// 运动方向 /// 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> maplist = new List
>(); Map map; Serpent serpent; Graphics g; int level = 1; ///
/// 运行线程 /// Thread Work_Thread = null; ////// 运行线程监控值 /// 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();//加载障碍物列表 } ////// 默认将地图设置为30*40 /// private void SetMap() { map.ResetMap(); g.Clear(map.BgColor); map.SetBorder();//设置边界 ListhiderList = GetHider();//获取障碍物列表 map.SetHinder(hiderList);//设置障碍物 SetSerpent();//初始化蛇 } /// /// 设置蛇 /// private void SetSerpent() { serpent = new Serpent(15, 5, this.panel1); serpent.InitializeSerpent();//初始化蛇 } ////// 获取地图障碍物列表 以增加不同级别难度 /// private void LoadMapList() { //目前分为5个级别 //第一级别 ListhiderList1 = new List (); for (int i = 15; i < 25; i++) { hiderList1.Add(map.GetNode(i, 15)); hiderList1.Add(map.GetNode(15, i)); } maplist.Add(hiderList1); //第二级别 List hiderList2 = new List (); for (int i = 7; i < 25; i++) { hiderList2.Add(map.GetNode(i, 15)); hiderList2.Add(map.GetNode(15, i)); } maplist.Add(hiderList2); //第三级别 List hiderList3 = new List (); 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 hiderList4 = new List (); 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 hiderList5 = new List (); 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); } /// /// 获取障碍物列表 /// ///private List GetHider() { //这里可以添加多个地图,当级别改变时需要重新加载 return maplist[level - 1]; } /// /// 重置地图 /// /// /// private void btnResetMap_Click(object sender, EventArgs e) { IsWork = false; btnStop.Enabled = false; button3.Enabled = false; button2.Enabled = true; //map.ResetMap(); SetMap(); } ////// 运行 /// 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(); } ////// 开始 /// /// /// 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; } } } ////// 暂停 /// /// /// 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; } } ////// 退出 /// /// /// 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(); } ////// 移动 /// /// 将要移动到的节点 ///返回状态 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 } }
主界面
以上就是关于C#如何实现贪吃蛇游戏的内容,如果你们有学习到知识或者技能,可以把它分享出去让更多的人看到。
本文题目:C#如何实现贪吃蛇游戏
文章源于:http://hbruida.cn/article/jpegdo.html