天天看点

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
    }
}      

继续阅读