天天看點

c# winfrom 貪食蛇遊戲

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;

namespace WinSnakeGame
{
    public partial class frmSnakePlus : Form
    {
        #region 遊戲變量

        /// <summary>
        /// 貪食蛇初始長度
        /// </summary>
        private int snakeCount
        {
            get { return Convert.ToInt32(cmbSnakeCount.SelectedItem); }
        }

        /// <summary>
        /// 貪食蛇初始大小
        /// </summary>
        private int snakeSize
        {
            get { return Convert.ToInt32(cmbSnakeSize.SelectedItem); }
        }

        /// <summary>
        /// 食物數量
        /// </summary>
        private int foodCount
        {
            get { return Convert.ToInt32(cmbFoodCount.SelectedItem); }
        }

        /// <summary>
        /// 爬行速度
        /// </summary>
        private int snakeSpeed
        {
            get { return Convert.ToInt32(cmbSpeed.SelectedItem); }
        }

        /// <summary>
        /// 貪食蛇分數
        /// </summary>
        private int snakeScore = 0;

        /// <summary>
        /// 正在爬行
        /// </summary>
        private bool snakeAction = false;

        /// <summary>
        /// 爬行方向
        /// </summary>
        private Keys KeyCode = Keys.Right;

        /// <summary>
        /// 組成貪食蛇的集合
        /// </summary>
        private List<Label> snakeCells = new List<Label>();

        /// <summary>
        /// 食物集合
        /// </summary>
        private List<Label> foodCells = new List<Label>();
        #endregion

        #region 構造函數
        public frmSnakePlus()
        {
            InitializeComponent();
        }

        private void frmSnakePlus_Load(object sender, EventArgs e)
        {
            cmbSnakeCount.SelectedItem = "1";
            cmbSnakeSize.SelectedItem = "10";
            cmbFoodCount.SelectedItem = "10";
            cmbSpeed.SelectedItem = "100";
            chbNodie.Checked = false;

            InitGame();
        }
        #endregion

        #region 遊戲控制

        /// <summary>
        /// 初始遊戲
        /// </summary>
        private void InitGame()
        {
            this.SnakeTimer.Stop();
            this.snakeAction = false;
            this.KeyPreview = true;
            this.DrawPanel.Focus();
            this.KeyCode = Keys.Right;
            this.snakeScore = this.snakeCount;

            btnStart.Enabled = true;
            btnClose.Enabled = btnStop.Enabled = false;

            // 清空貪食蛇
            snakeCells.Clear();

            // 清空食物
            foodCells.Clear();

            // 清空遊戲區域
            DrawPanel.Controls.Clear();

            InitSnake();

            InitFood();
        }

        /// <summary>
        /// 初始化貪食蛇
        /// </summary>
        private void InitSnake()
        {
            // 初始化貪食蛇
            for (int i = snakeScore - 1; i >= 0; i--)
            {
                // 建立方格
                Label _cell = CreateCell(new Point(i * this.snakeSize, 0));

                // 将方格添加到蛇身集合
                snakeCells.Add(_cell);

                // 繪制到遊戲區域
                this.DrawPanel.Controls.Add(_cell);
            }

            // 顯示資訊
            SnakePoint.Text = string.Format("X:{0}    Y:{1}    snakeScore:{2}", snakeCells[0].Location.X, snakeCells[0].Location.Y, snakeScore);

        }

        /// <summary>
        /// 開始遊戲
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStart_Click(object sender, EventArgs e)
        {
            btnStop.Enabled = btnClose.Enabled = true;
            btnStart.Enabled = false;

            this.snakeAction = true;
            this.SnakeTimer.Start();
        }

        /// <summary>
        /// 暫停遊戲
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStop_Click(object sender, EventArgs e)
        {
            btnStart.Enabled = btnClose.Enabled = true;
            btnStop.Enabled = false;

            this.snakeAction = false;
            this.SnakeTimer.Stop();
        }

        /// <summary>
        /// 結束遊戲
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClose_Click(object sender, EventArgs e)
        {
            btnStart.Enabled = true;
            btnStop.Enabled = btnClose.Enabled = false;

            this.InitGame();
        }

        /// <summary>
        /// 定時控件:控制貪食蛇的自動運動
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SnakeTimer_Tick(object sender, EventArgs e)
        {

            int xRan = snakeCells[0].Location.X;
            int yRan = snakeCells[0].Location.Y;

            if (this.KeyCode == Keys.Up)
            {
                yRan -= this.snakeSize;   //向上移動
            }
            else if (this.KeyCode == Keys.Down)
            {
                yRan += this.snakeSize;   //向下移動
            }
            else if (this.KeyCode == Keys.Left)
            {
                xRan -= this.snakeSize;   //向左移動
            }
            else if (this.KeyCode == Keys.Right)
            {
                xRan += this.snakeSize;   //向右移動
            }

            bool isOut = (xRan < 0 || xRan > (this.DrawPanel.Height - this.snakeSize) || yRan < 0 || yRan > (this.DrawPanel.Height - this.snakeSize));

            // 檢測貪食蛇是否在遊戲區域中
            if (isOut && !chbNodie.Checked)
            {
                this.SnakeTimer.Stop();
                MessageBox.Show("Game Over!");
                this.InitGame();
                return;
            }
            // 無敵模式:穿牆設定
            else if (isOut && chbNodie.Checked)
            {
                if (xRan > this.DrawPanel.Width)
                {
                    xRan = 0;
                }
                if (xRan < 0)
                {
                    xRan = this.DrawPanel.Width;
                }
                if (yRan > this.DrawPanel.Height)
                {
                    yRan = 0;
                }
                if (yRan < 0)
                {
                    yRan = this.DrawPanel.Height;
                }
            }
            for (int i = snakeScore - 1; i > 0; i--)
            {
                // 蛇身所有格子前進到前一個格子的位置
                snakeCells[i].Location = new Point(snakeCells[i - 1].Location.X, snakeCells[i - 1].Location.Y);
            }

            // 蛇頭前進一個格子
            snakeCells[0].Location = new Point(xRan, yRan);

            List<Label> _findFoods = foodCells.Where(n => n.Location == snakeCells[0].Location).ToList<Label>();

            for (int i = 0; i < _findFoods.Count(); i++)
            {
                // 消除遊戲區域中的食物
                this.DrawPanel.Controls.Remove(_findFoods[i]);

                //消除數組中的食物
                foodCells.Remove(_findFoods[i]);

                // 蛇身變長
                Label _cell = CreateCell(snakeCells[snakeCells.Count - 1].Location, Color.Blue);
                snakeCells.Add(_cell);
                this.DrawPanel.Controls.Add(_cell);

                //增加蛇身長度
                snakeScore++;
            }

            if (foodCells.Count == 0)
            {
                InitFood();
            }

            SnakePoint.Text = string.Format("X:{0}    Y:{1}    snakeScore:{2}", snakeCells[0].Location.X, snakeCells[0].Location.Y, snakeScore);
        }

        /// <summary>
        /// 監控方向鍵:改變貪食蛇的運動方向(上下左右)
        /// </summary>
        /// <param name="keyCode"></param>
        /// <returns></returns>
        protected override bool ProcessDialogKey(Keys _keyCode)
        {
            // 隻對上下左右按鍵做出響應
            if (_keyCode == Keys.Up || _keyCode == Keys.Down || _keyCode == Keys.Left || _keyCode == Keys.Right)
            {

                // 記錄按下的方向鍵
                this.KeyCode = _keyCode;

                if (!snakeAction)
                {
                    snakeAction = true;
                    SnakeTimer.Start();

                    btnStop.Enabled = btnClose.Enabled = true;
                    btnStart.Enabled = false;
                }

                return false;
            }
            else
            {
                return base.ProcessDialogKey(_keyCode);
            }
        }
        #endregion

        #region 生産食物
        /// <summary>
        /// 食物初始化
        /// </summary>
        private void InitFood()
        {
            CreateFood(foodCount);
        }

        /// <summary>
        ///生産食物
        /// </summary>
        /// <param name="foodCount"></param>
        private void CreateFood(int foodCount)
        {
            Random ran = new Random();//随機類
            int xRan, yRan;

            for (int i = 0; i < foodCount; i++)
            {
                // 随機生成食物放置的X、Y坐标
                xRan = ran.Next(0, this.DrawPanel.Width / this.snakeSize) * this.snakeSize;
                yRan = ran.Next(0, this.DrawPanel.Height / this.snakeSize) * this.snakeSize;

                if (xRan > this.DrawPanel.Width - 10 || xRan > this.DrawPanel.Height - 10)
                {
                    xRan = ran.Next(0, this.DrawPanel.Width / snakeSize) * snakeSize;
                    yRan = ran.Next(0, this.DrawPanel.Height / snakeSize) * snakeSize;
                }

                Point FoodPoint = new Point(xRan, yRan);

                // 檢索指定坐标處的子控件
                var newFood = this.DrawPanel.GetChildAtPoint(FoodPoint);
                if (newFood == null)
                {
                    // 建立方格
                    Label _cell = CreateCell(FoodPoint, Color.White);

                    // 将方格添加到食物集合
                    foodCells.Add(_cell);

                    // 繪制到遊戲區域
                    this.DrawPanel.Controls.Add(_cell);
                }
            }
        }
        #endregion

        #region 通用方法
        /// <summary>
        /// 建立格子
        /// </summary>
        /// <returns></returns>
        private Label CreateCell(Point point)
        {
            Label _cell = new Label();
            _cell.Size = new Size(this.snakeSize, this.snakeSize);
            _cell.Location = point;
            _cell.BackColor = Color.Red;
            _cell.BorderStyle = BorderStyle.FixedSingle;
            return _cell;
        }

        /// <summary>
        /// 建立格子
        /// </summary>
        /// <returns></returns>
        private Label CreateCell(Point point, Color color)
        {
            Label _cell = new Label();
            _cell.Size = new Size(this.snakeSize, this.snakeSize);
            _cell.Location = point;
            _cell.BackColor = color;
            _cell.BorderStyle = BorderStyle.FixedSingle;
            return _cell;
        }
        #endregion

        #region Event
        private void btnSetting_Click(object sender, EventArgs e)
        {
            if (this.Height == 589)
            {
                this.Height = 660;
            }
            else
            {
                this.Height = 589;
            }
        }

        /// <summary>
        /// 設定初始長度
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbSnakeCount_SelectedIndexChanged(object sender, EventArgs e)
        {
            InitGame();
        }

        /// <summary>
        /// 設定初始大小
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbSnakeSize_SelectedIndexChanged(object sender, EventArgs e)
        {
            InitGame();
        }

        /// <summary>
        /// 設定食物數量
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbFoodCount_SelectedIndexChanged(object sender, EventArgs e)
        {
            InitGame();
        }

        /// <summary>
        /// 開啟無敵模式
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chbNodie_CheckedChanged(object sender, EventArgs e)
        {
            //InitGame();

            this.KeyPreview = true;
            this.DrawPanel.Focus();
        }

        /// <summary>
        /// 設定爬行速度
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbSpeed_SelectedIndexChanged(object sender, EventArgs e)
        {
            SnakeTimer.Interval = this.snakeSpeed;

            this.KeyPreview = true;
            this.DrawPanel.Focus();
        }
        #endregion
    }
}      

繼續閱讀