這篇文章主要為大家展示了C#如何實(shí)現(xiàn)貪吃蛇游戲,內(nèi)容簡而易懂,希望大家可以學(xué)習(xí)一下,學(xué)習(xí)完之后肯定會(huì)有收獲的,下面讓小編帶大家一起來看看吧。
成都創(chuàng)新互聯(lián)公司主營巴州網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,成都App定制開發(fā),巴州h5小程序開發(fā)搭建,巴州網(wǎng)站營銷推廣歡迎巴州等地區(qū)企業(yè)咨詢
貪吃蛇分析
游戲規(guī)則:
1、蛇起始長度5,每吃一個(gè)食物增加1,最大15過關(guān)
2、蛇用藍(lán)色表示,食物用綠色,障礙物用黑色
3、當(dāng)蛇碰到自己、墻壁、障礙物則游戲失敗
4、方向鍵控制蛇的移動(dòng)方向,蛇不可反方向移動(dòng),如正在向上移動(dòng),不能馬上向下,只能向左、右、上運(yùn)動(dòng)
5、每過關(guān)一次速度提升一次
大概思路:
1、地圖用網(wǎng)格的形式表示,蛇由方格組成,保存在list中
2、1中提到了方格,方格保存的內(nèi)容有,顏色,坐標(biāo),是否可以通過,是否是食物
3、向前移動(dòng)一次,將前面方格添加進(jìn)蛇列表中,將列表最后一個(gè)移除,若為前方格子為食物,則不移除最后一個(gè)
4、使用while死循環(huán)來做整個(gè)移動(dòng)
5、空格鍵為加速鍵,通過修改while循環(huán)sleep時(shí)間來實(shí)現(xiàn)加速
包括了3個(gè)類一個(gè)主窗體,分別是Node(用來表示方格)、Map(用來表示地圖)、Serpent(用來表示蛇),另外一個(gè)主窗體。下面依次把代碼貼上,基本上每個(gè)方法都有注釋
代碼1:
using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace EngorgeSerpent { ////// 節(jié)點(diǎn) /// 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 ////// 設(shè)置食物參數(shù) /// /// public void SetFood(bool _isFood) { IsFood = _isFood; if (_isFood) { ThisColor = FoodColor; } else { ThisColor = BgColor; } } ////// 設(shè)置障礙物參數(shù) /// /// 是否為障礙物 public void SetHinder(bool _isHinder) { IsPass =! _isHinder; if (_isHinder) { ThisColor = HinderColor; } else { ThisColor = BgColor; } } ////// 設(shè)置蛇顏色 /// /// public void SetSerpent(bool _isSerpent) { IsPass = !_isSerpent; if (_isSerpent) { ThisColor = SerpentColor; } else { ThisColor = BgColor; } } #region 構(gòu)造函數(shù) public Node() { thisColor = bgColor; } ////// 有參構(gòu)造方法 /// /// 相對(duì)x坐標(biāo) /// 相對(duì)y坐標(biāo) /// 邊長 /// 是否是食物 /// 是否可通過 public Node(int _x, int _y, int _width, bool _isFood, bool _isPass) { thisColor = bgColor; X = _x; Y = _y; Width = _width; IsFood = _isFood; IsPass = _isPass; } ////// 有參構(gòu)造方法 /// /// 相對(duì)x坐標(biāo) /// 相對(duì)y坐標(biāo) /// 邊長 public Node(int _x, int _y, int _width) { X = _x; Y = _y; Width = _width; } ////// 有參構(gòu)造方法 /// /// 相對(duì)x坐標(biāo) /// 相對(duì)y坐標(biāo) 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; } } ////// 當(dāng)前顏色 /// public Color ThisColor { get { return thisColor; } set { thisColor = value; } } ////// 獲取或設(shè)置相對(duì)橫坐標(biāo) /// public int X { get { return x; } set { x = value; } } ////// 獲取或設(shè)置相對(duì)縱坐標(biāo) /// public int Y { get { return y; } set { y = value; } } ////// 獲取或設(shè)置節(jié)點(diǎn)邊長 /// public int Width { get { return width; } set { width = value; } } ////// 獲取或設(shè)置是否為食物 /// public bool IsFood { get { return isFood; } set { isFood = value; } } ////// 獲取或設(shè)置是否可以通過 /// 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 { ////// 節(jié)點(diǎn)數(shù)組 /// 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; } } ////// 構(gòu)造方法 /// /// 行數(shù) /// 列數(shù) 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); } } /// /// 構(gòu)造方法 /// /// 行數(shù) /// 列數(shù) /// 節(jié)點(diǎn)寬度 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; } } } ////// 獲得節(jié)點(diǎn) /// /// /// ///public Node GetNode(int x, int y) { return _nodes[y][x]; } /// /// 設(shè)置食物 /// 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); } ////// 設(shè)置障礙物 /// /// 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); } /// /// 設(shè)置邊界 /// public void SetBorder() { //通過計(jì)算得出邊界的個(gè)數(shù)是2(x+y-2)個(gè)方格 SolidBrush brush = null; int borders = 2 * (ComsCount + RowCount - 2); RectangleF[] rects = new RectangleF[borders]; int indexcount = 0; //添加頂部方格進(jìn)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++; } //添加底部方格進(jìn)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++; } //添加左側(cè)方格進(jìn)列表,因?yàn)樽髠?cè)最上面以及最下面的兩個(gè)方格已經(jīng)添加進(jìn)去,這里不需要重復(fù)添加 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++; } //添加右側(cè)方格進(jìn)列表,因?yàn)橛覀?cè)最上面以及最下面兩個(gè)方格已經(jīng)添加進(jìn)去,這里不需要重復(fù)添加 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;//運(yùn)動(dòng)方向 private int maxCount = 15; private int minCount = 5; private System.Windows.Forms.Control MapPanel; Graphics g; /// /// 設(shè)置蛇長度數(shù)據(jù) /// /// 最大長度 /// 最小長度 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);//設(shè)置蛇顏色 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); } ////// 插入一個(gè) /// /// 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; } /// /// 蛇運(yùn)動(dòng)方向 /// public Direction Direction { get { return direction; } set { direction = value; } } } ////// 運(yùn)動(dòng)方向 /// 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; ///
/// 運(yùn)行線程 /// Thread Work_Thread = null; ////// 運(yùn)行線程監(jiān)控值 /// 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);//這里可以對(duì)畫布進(jìn)行下大小設(shè)置 此處偷懶省略 LoadMapList();//加載障礙物列表 } ////// 默認(rèn)將地圖設(shè)置為30*40 /// private void SetMap() { map.ResetMap(); g.Clear(map.BgColor); map.SetBorder();//設(shè)置邊界 ListhiderList = GetHider();//獲取障礙物列表 map.SetHinder(hiderList);//設(shè)置障礙物 SetSerpent();//初始化蛇 } /// /// 設(shè)置蛇 /// private void SetSerpent() { serpent = new Serpent(15, 5, this.panel1); serpent.InitializeSerpent();//初始化蛇 } ////// 獲取地圖障礙物列表 以增加不同級(jí)別難度 /// private void LoadMapList() { //目前分為5個(gè)級(jí)別 //第一級(jí)別 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); //第二級(jí)別 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); //第三級(jí)別 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); //第四級(jí)別 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); //第五級(jí)別 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() { //這里可以添加多個(gè)地圖,當(dāng)級(jí)別改變時(shí)需要重新加載 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(); } ////// 運(yùn)行 /// private void Work() { map.SetFood();//設(shè)置食物 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)//游戲結(jié)束 { IsWork = false; //map.ResetMap(); MessageBox.Show("游戲結(jié)束!", "提示", 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 = "繼續(xù)"; 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 = "繼續(xù)"; 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(); } ////// 移動(dòng) /// /// 將要移動(dòng)到的節(jié)點(diǎn) ///返回狀態(tài) private SerpentState SerpentMove(Node node) { if (!node.IsPass) { return SerpentState.Error; } serpent.InsertNode(node); if (!node.IsFood) { //不是食物,則移除最后一個(gè)節(jié)點(diǎn) serpent.RemoveNode(); } else { lblCount.BeginInvoke(new MethodInvoker(delegate() { this.lblCount.Text = (Convert.ToInt32(this.lblCount.Text.Trim()) + 1).ToString(); })); map.SetFood();//設(shè)置食物 } 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 } }
主界面
以上就是關(guān)于C#如何實(shí)現(xiàn)貪吃蛇游戲的內(nèi)容,如果你們有學(xué)習(xí)到知識(shí)或者技能,可以把它分享出去讓更多的人看到。