简单贪吃蛇的编程设计

这两天花了点时间写了贪吃蛇这个小程序,现在将大体的设计过程描述一下,源程序请在www.csdn.net下载,我的用户名为andamajing。

简单的分析一下,贪吃蛇从总体上说显示和控制两大部分,第一方面显示部分包含窗体的整体布局,游戏活动部分的显示,以及得分的显示,游戏帮助和关于这个游戏的说明;第二方面是控制部分,控制部分包含游戏中蛇和食物的颜色设置,开始,暂停,停止等控制按键以及方向键的控制。

首先对于蛇,我们需要定义一个类,这个类包含蛇的组成单元及大小,蛇的颜色,蛇的长度和蛇的运动方向等基本字段,蛇的移动,吃食物等基本方法,以及是否死亡等标识。具体定义如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Collections;

namespace SnakeGame
{
    class Snake
    {
        //蛇身单元
        private Label bodyCeil;
        //蛇身单元大小
        static private Size size=new Size(10,10);
        //蛇身颜色
        public  Color snakeColor;
        //蛇身链表
        ArrayList snake = new ArrayList();
        //蛇身长度
        private int snakeLength=5;
        public int SnakeLength
        {
            get
            {
                return snake.Count;
            }
        }
        //蛇运动方向,初始向右
        private Direction snakeDirection=Direction.Right;
        public Direction SnakeDirection
        {
            get
            {
                return snakeDirection;
            }
            set
            {
                snakeDirection=value;
            }
        }
        //食物是否吃完标志
        private bool flag = false;
        public bool Flag
        {
            get
            {
                return flag;
            }
            set
            {
                flag = value;
            }
        }
        //画初始蛇体
        private void DrawBeginSnake()
        {
            for (int i = 0; i < 5; i++)
            {
                bodyCeil = new Label();
                bodyCeil.BackColor = snakeColor;
                bodyCeil.Size = size;
                bodyCeil.Location = new Point(40 - i * 10, 0);
                bodyCeil.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
                snake.Add(bodyCeil);
            }
        }
        
        //带参数的构造函数,可设置蛇身颜色
        public Snake(Color newcolor)
        {
            snakeColor = newcolor;
            DrawBeginSnake();
        }
        //返回蛇体
        public ArrayList GetSnake()
        {
            return snake;
        }
        //是否有食物标志
        private bool hasFood = false;
        //定义蛇是否死亡标志,true为死亡,false为没死
        private bool isDead = false;
        public bool IsDead
        {
            get
            {
                return isDead;
            }
        }
        //蛇移动
        public void Move(System.Windows.Forms.Control control,Label food)
        {
            if (!hasFood)
            {
                control.Controls.Remove(control.GetChildAtPoint(((Label)snake[snake.Count-1]).Location));
                snake.RemoveAt(snake.Count - 1);
            }
            Label snakeHead = new Label();
            CopySnakeBodyCeil(snakeHead, (Label)snake[0]);
            switch (snakeDirection)
            { 
                case Direction.Up:
                    snakeHead.Top -= 10;
                    if (snakeHead.Top < 0)
                        isDead = true;
                    break;
                case Direction.Down:
                    snakeHead.Top += 10;
                    if (snakeHead.Top > 270)
                        isDead = true;
                    break;
                case Direction.Left:
                    snakeHead.Left-= 10;
                    if (snakeHead.Left < 0)
                        isDead = true;
                    break;
                case Direction.Right:
                    snakeHead.Left+= 10;
                    if (snakeHead.Left > 340)
                        isDead = true;
                    break;
            }
            snake.Insert(0, snakeHead);
            if (hasFood)
            {
                hasFood = false;
                control.Controls.Remove(control.GetChildAtPoint(food.Location));
                //control.Controls.Clear();
                this.flag = true;
            }
        }
        //复制蛇单元
        private void CopySnakeBodyCeil(Label to, Label from)
        {
            to.BackColor = from.BackColor;
            to.Size = from.Size;
            to.Location = from.Location;
            to.BorderStyle = from.BorderStyle;
        }
        //判断是否有食物标志
        public void EatFood(Label _food)
        {
            switch (snakeDirection)
            { 
                case Direction.Up:
                    if (((Label)snake[0]).Left == _food.Left && ((Label)snake[0]).Top == _food.Top + 10)
                        hasFood = true;
                    else
                        hasFood = false;
                    break;
                case Direction.Down:
                    if (((Label)snake[0]).Left == _food.Left && ((Label)snake[0]).Top == _food.Top - 10)
                        hasFood = true;
                    else
                        hasFood = false;
                    break;
                case Direction.Left:
                    if (((Label)snake[0]).Left == _food.Left + 10 && ((Label)snake[0]).Top == _food.Top)
                        hasFood = true;
                    else
                        hasFood = false;
                    break;
                case Direction.Right:
                    if (((Label)snake[0]).Left == _food.Left - 10 && ((Label)snake[0]).Top == _food.Top )
                        hasFood = true;
                    else
                        hasFood = false;
                    break;
            }
        }
    }
}

接下来就是食物的定义了,具体第一如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace SnakeGame
{
    class Food
    {
        //定义一个食物
        private Label foodCeil=new Label();
        public Label FoodCeil
        {
            get
            {
                return foodCeil;
            }
            set
            {
                foodCeil = value;
            }
        }
        //定义食物的颜色
        private Color foodColor;
        public Color FoodColor
        {
            get
            {
                return foodColor;
            }
        }
        //定义食物位置
        private Point foodLocation;
        public Point FoodLocation
        {
            get
            {
                return new Point(foodCeil.Top, foodCeil.Left);
            }
        }
        //定义食物的大小
        private static Size foodSize = new Size(10, 10);
        
        //构造函数,
        public Food(Color color,Point point)
        {
            foodCeil.Size = foodSize;
            foodCeil.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            foodCeil.BackColor = color;
            foodCeil.Left = point.X;
            foodCeil.Top = point.Y;
            foodColor = color;
        }     
  
        //复制食物单元
        public void CopyFoodCeil(Label to, Label from)
        {
            to.BackColor = from.BackColor;
            to.Size = from.Size;
            to.Location = from.Location;
            to.BorderStyle = from.BorderStyle;
        }
    }
}

上面两个类定义了这个游戏中的两个对象,接下来就需要在主题的显示界面中去控制蛇的运动,主题的界面如下所示:



运行的界面如下所示:

游戏结束的画面如下:

设置颜色的窗体显示如下:

接下来说一下主程序中控制程序,在程序中控制菜单项和按键如何进行处理。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SnakeGame.Properties;

namespace SnakeGame
{
    public partial class FormSnakeGame : Form
    {
        //定义一个蛇
        private Snake mySnake;
        //定义一个食物
        private Food myFood;
        //定义蛇颜色
        private Color mySnakeColor;
        //定义食物颜色
        private Color myFoodColor;
        //定义一个颜色设置窗口
        颜色设置 gameColorSetting =new 颜色设置();
      
        public FormSnakeGame()
        {
            InitializeComponent();
            this.buttonStop.Enabled = false;
            ClearDirection();
            this.低水平ToolStripMenuItem.Checked = true;
            this.panelGame.BackgroundImage = Resources.myblog;
        }

        private void 游戏说明ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            游戏操作 gameOperationInformation = new 游戏操作();
            gameOperationInformation.Show();
        }

        private void 关于ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            关于 gameAbout = new 关于();
            gameAbout.Show();
        }

        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void 颜色设置ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //gameColorSetting = new 颜色设置();
            gameColorSetting.Show();
        }
        
        //停止或暂停按键按下
        private static int i = 0;//用于判断显示Stop还是显示Continue
        private void buttonStop_Click(object sender, EventArgs e)
        {
            if (i++ % 2 == 0)
            {
                this.buttonStop.Text = "Continue";
                this.timerSnakeSpeed.Enabled = false;
            }
            else
            {
                this.buttonStop.Text = "Stop";
                this.timerSnakeSpeed.Enabled = true;
            }
        }

        //开始按键按下
        private void buttonStart_Click(object sender, EventArgs e)
        {
            this.panelGame.BackgroundImage = null;
            this.buttonStart.Enabled = false;
            EnableDirection();
            mySnakeColor = gameColorSetting.SetSnakeColor;
            myFoodColor = gameColorSetting.SetFoodColor;
            this.buttonStop.Enabled = true;
            mySnake = new Snake(mySnakeColor);
            foreach (Label lbl in mySnake.GetSnake())
            {
                this.panelGame.Controls.Add(lbl);
            }
            myFood = new Food(myFoodColor,new Point(100,100));
            this.panelGame.Controls.Add(myFood.FoodCeil);
            this.myFood.CopyFoodCeil(currentfood, this.myFood.FoodCeil);
            this.timerSnakeSpeed.Enabled = true;//启动计时器
        }

        //画蛇函数
        private void DrawSnake(Snake _newsnake)
        {
            foreach (Label lbl in _newsnake.GetSnake())
            {
                this.panelGame.Controls.Add(lbl);
            }
        }

        //定义一个Label存放当前食物
        Label currentfood = new Label();
        //发放食物
        private void PutFood()
        {
            Random randfood = new Random();
            int newfoodx = randfood.Next(35);
            int newfoody = randfood.Next(28);
            Label newfood = new Label();
            this.myFood.CopyFoodCeil(newfood, currentfood);
            newfood.Left = newfoodx*10;
            newfood.Top = newfoody*10;
            this.panelGame.Controls.Remove(this.myFood.FoodCeil);
            this.panelGame.Controls.Add(newfood);
            this.myFood.CopyFoodCeil(this.myFood.FoodCeil, newfood);
            this.myFood.CopyFoodCeil(currentfood, newfood);
        }

        //画食物函数
        private void DrawFood(Label newfood)
        {
            this.panelGame.Controls.Add(newfood);
        }

        //移除食物
        private void RemoveFood(Label oldfood)
        {
            this.panelGame.Controls.Remove(oldfood);
        }

        //计时器函数
        private void timerSnakeSpeed_Tick(object sender, EventArgs e)
        {
            mySnake.EatFood(this.myFood.FoodCeil);
            mySnake.Move(this.panelGame,this.myFood.FoodCeil);
            DrawSnake(mySnake);
            if (this.mySnake.IsDead)
            {
                this.buttonStart.Enabled = true;
                this.buttonStop.Enabled = false;
                this.timerSnakeSpeed.Enabled = false;
                ClearColor();
                ClearDirection();
                this.textBoxScore.Text = "";
                this.panelGame.Controls.Clear();
                this.panelGame.BackgroundImage = Resources.gameover1;
            }
            if (mySnake.Flag)
            {
                PutFood();
                mySnake.Flag = false;
            }
            this.textBoxScore.Text = ((mySnake.SnakeLength - 5) * 10).ToString();
        }

        //清除水平选择标志
        private void ClearFlag()
        {
            this.低水平ToolStripMenuItem.Checked = false;
            this.普通水平ToolStripMenuItem.Checked = false;
            this.高水平ToolStripMenuItem.Checked = false;
        }

        //选择普通水平
        private void 普通水平ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ClearFlag();
            this.普通水平ToolStripMenuItem.Checked = true ;
            this.timerSnakeSpeed.Interval = 300;
        }

        private void 高水平ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ClearFlag();
            this.高水平ToolStripMenuItem.Checked = true;
            this.timerSnakeSpeed.Interval = 200;
        }

        private void 低水平ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ClearFlag();
            this.低水平ToolStripMenuItem.Checked = true;
            this.timerSnakeSpeed.Interval = 400;
        }

        //按键处理程序
        private void FormSnakeGame_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 'a' || e.KeyChar == 'A')
            { 
                this.mySnake.SnakeDirection=(this.mySnake.SnakeDirection==Direction.Right?Direction.Right:Direction.Left);
                ClearColor();
                this.buttonKeyA.BackColor = Color.Blue;
            }
            else if (e.KeyChar == 'd' || e.KeyChar == 'D')
            {
                this.mySnake.SnakeDirection = (this.mySnake.SnakeDirection == Direction.Left ? Direction.Left : Direction.Right);
                ClearColor();
                this.buttonKeyD.BackColor = Color.Blue;
            }
            else if (e.KeyChar == 'w' || e.KeyChar == 'W')
            {
                this.mySnake.SnakeDirection = (this.mySnake.SnakeDirection == Direction.Down ? Direction.Down : Direction.Up);
                ClearColor();
                this.buttonKeyW.BackColor = Color.Blue;
            }
            else if (e.KeyChar == 's' || e.KeyChar == 'S')
            {
                this.mySnake.SnakeDirection = (this.mySnake.SnakeDirection == Direction.Up ? Direction.Up : Direction.Down);
                ClearColor();
                this.buttonKeyS.BackColor = Color.Blue;
            }
            else
            {
                e.Handled = true;
            }
        }
        //W键按下
        private void buttonKeyW_Click(object sender, EventArgs e)
        {
            this.mySnake.SnakeDirection = (this.mySnake.SnakeDirection == Direction.Down ? Direction.Down : Direction.Up);
            ClearColor();
            this.buttonKeyW.BackColor = Color.Blue;
        }
        //A键按下
        private void buttonKeyA_Click(object sender, EventArgs e)
        {
            this.mySnake.SnakeDirection = (this.mySnake.SnakeDirection == Direction.Right ? Direction.Right : Direction.Left);
            ClearColor();
            this.buttonKeyA.BackColor = Color.Blue;
        }
        //S键按下
        private void buttonKeyS_Click(object sender, EventArgs e)
        {
            this.mySnake.SnakeDirection = (this.mySnake.SnakeDirection == Direction.Up ? Direction.Up : Direction.Down);
            ClearColor();
            this.buttonKeyS.BackColor = Color.Blue;
        }
        //D键按下
        private void buttonKeyD_Click(object sender, EventArgs e)
        {
            this.mySnake.SnakeDirection = (this.mySnake.SnakeDirection == Direction.Left ? Direction.Left : Direction.Right);
            ClearColor();
            this.buttonKeyD.BackColor = Color.Blue;
        }
        //清除方向键背景颜色
        private void ClearColor()
        {
            this.buttonKeyW.BackColor = System.Windows.Forms.Button.DefaultBackColor;
            this.buttonKeyA.BackColor = System.Windows.Forms.Button.DefaultBackColor;
            this.buttonKeyS.BackColor = System.Windows.Forms.Button.DefaultBackColor;
            this.buttonKeyD.BackColor = System.Windows.Forms.Button.DefaultBackColor;
        }
        //方向键不可用
        private void ClearDirection()
        {
            this.buttonKeyA.Enabled = false;
            this.buttonKeyW.Enabled = false;
            this.buttonKeyD.Enabled = false;
            this.buttonKeyS.Enabled = false;
        }
        //方向键可用
        private void EnableDirection()
        {
            this.buttonKeyA.Enabled = true;
            this.buttonKeyW.Enabled = true;
            this.buttonKeyD.Enabled = true;
            this.buttonKeyS.Enabled = true;
        }
    }
}

上面简单的介绍了一下贪吃蛇的编程,大家相互交流,呵呵....

你可能感兴趣的:(C#项目)