利用C#实现简单的贪吃蛇

C#生存简单的贪吃蛇游戏

功能实现:

  1. 贪吃蛇的左右上下移动;
  2. 贪吃蛇吃食物;
  3. 贪吃蛇碰到墙或者身体死亡;

效果如图:
利用C#实现简单的贪吃蛇_第1张图片

如下是 详细的代码:

1. 主函数 Program.cs

using System;
using System.Threading;
namespace CmdSnake
{
    class Program
    {
        static void Main(string[] args)
        {

            /// 
            /// 初始化
            /// 
            Snake.Instance().Start();
            Map.Instance().Start();
            for (; ; )
            {
                Snake.Instance().Update();
                Map.Instance().Update();

                Map.Instance().Draw();
                Snake.Instance().Draw();

                Thread.Sleep(100); //延时

            }
        }
    }
}

2.地图部分 Map.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace CmdSnake
{
    class Map
    {
        private static Map instance = null;
        //建立单例
        public static Map Instance()
        {
            if (instance == null)
            {
                instance = new Map();
            }
            return instance;
        }
        /// 
        /// 
        /// 
        public const int Blank = 0;
        public const int Wall = 1;
        public const int Food = 2;

        int[,] map = null;

        private Random rnd = new Random();
        public int GetAt(Point pt)
        {
            return map[pt.y, pt.x];
        }
        public void SetAt(Point pt, int value)
        {
             map[pt.y, pt.x] = value;
        }
        /// 
        /// 生成食物规则:
        /// 1.只能在空地上生成
        /// 2.不能在蛇的身体生成
        /// 
        public void GenFood()
        {
            Point pt;
            for (; ; )
            {
                pt.x = rnd.Next(map.GetLength(1));
                pt.y = rnd.Next(map.GetLength(0));

                if (GetAt(pt) == Map.Blank)
                {
                    map[pt.x, pt.y] = Map.Food;
                    return;
                }
            }
        }

        /// 
        /// 初始化
        /// 
        public void Start()
        {
            map = new int[30, 30] //行 列
            {
                { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},                
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,},
                { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},
            };

            GenFood();
        }
        /// 
        /// 逻辑处理(数据运算)
        /// 
        public void Update()
        {

        }
        /// 
        /// 图形处理
        /// 
        public void Draw()
        {
            for (int i = 0; i < map.GetLength(0); i++) // i | 行
            {
                for (int j = 0; j < map.GetLength(1); j++) // j - 列
                {
                    Console.SetCursorPosition(j*2,i); //j*2两个格子
                    //Console.ForegroundColor = ConsoleColor.Yellow;
                    switch (map[i, j])
                    {
                        case Map.Wall:
                            Console.BackgroundColor = ConsoleColor.Green;
                            Console.ForegroundColor = ConsoleColor.Green;
                            Console.Write(' ');
                            break;
                        case Map.Food:
                            Console.BackgroundColor = ConsoleColor.Gray;
                            Console.ForegroundColor = ConsoleColor.DarkBlue;
                            Console.Write('●');
                            break;
                        case Map.Blank:
                            Console.BackgroundColor = ConsoleColor.Gray;
                            Console.ForegroundColor = ConsoleColor.Gray;
                            Console.Write(' ');
                            break;
                    }
                }
            
            }
        }
    }
}

3.移动方向部分 Direction.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace CmdSnake
{
    enum Direction
    {
        Left,  //左
        Right, //右
        Up,    //上
        Down,  //下
    }
}

4.坐标点部分 Point.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace CmdSnake
{
    //希望 S2 = S1 赋值的时候,是把S1的内容(x,y)拷贝给S2,而非让S2跟S1指向同一块内存(class),所以需要定义为struct
    struct Point
    {
        public int x;
        public int y;

        public  Point(int x,int y)
        {
            this.x = x;
            this.y = y;
        }
        //+运算符重载
        public static Point operator +(Point p1, Point p2)
        {
            return new Point(p1.x + p2.x, p1.y + p2.y);
        }

        //-运算符重载
        public static bool operator == (Point p1, Point p2)
        {
            return p1.x == p2.x && p1.y == p2.y;
        }
        public static bool operator !=(Point p1, Point p2)
        {
            return !(p1 == p2);
        }
    }
}

5.蛇主体部分 Snake.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace CmdSnake
{
    class Snake
    {
        private static Snake instance = null;
        public static Snake Instance()
        {
            if (instance == null)
            {
                instance = new Snake();
            }
            return instance;
        }

        List<Point> body = new List<Point>();

        Direction dir = Direction.Right;

        Point tail; //尾巴
        /// 
        /// 初始化
        /// 
        public void Start()
        {
            body.Add(new Point(4, 2));
            body.Add(new Point(3, 2));
            body.Add(new Point(2, 2));
        }
        /// 
        /// 判断依据:
        /// 1.蛇头是否碰上墙
        /// 2.蛇头是否碰上身体
        /// 
        ///  true:结束,false:进行中
        private bool IsGameOver()
        {
            Point head = body[0]; //蛇头的坐标

            //1.蛇头是否碰上墙
            if (Map.Instance().GetAt(head) == Map.Wall)
                return true;

            //2.蛇头是否碰上身体
            for (int i = 1; i < body.Count; i++)
            {
                if (body[i] == head) return true;
            }

            return false;
        }

        /// 
        /// 处理转向判定
        /// 注意:只能往蛇的前进的侧方向转向
        /// 1.获取按键输入
        /// 2.判定是否能移动
        /// 改变dir
        /// 
        private void Turn()
        {
            //1.按键输入
            if (Console.KeyAvailable)
            {
                ConsoleKey key = Console.ReadKey(true).Key;

                //2.判定是否能移动
                if (key == ConsoleKey.LeftArrow && dir != Direction.Right)
                {
                    dir = Direction.Left;
                }
                else if (key == ConsoleKey.RightArrow && dir != Direction.Left)
                {
                    dir = Direction.Right;
                }
                else if (key == ConsoleKey.UpArrow && dir != Direction.Down)
                {
                    dir = Direction.Up;
                }
                else if (key == ConsoleKey.DownArrow && dir != Direction.Up)
                {
                    dir = Direction.Down;
                }

            }
        }

        /// 
        /// 根据蛇的移动方向dir在地图上前进
        /// 
        private void Move()
        {
            Point offset =new Point(0,0); //偏移量
            switch (dir)
            {
                case Direction.Left:
                    offset = new Point(-1,0);break;
                case Direction.Right:
                    offset = new Point(1,0); break;
                case Direction.Up:
                    offset = new Point(0,-1); break;
                case Direction.Down:
                    offset = new Point(0,1); break;
            }

            Point head = body[0];
            head += offset;

            body.Insert(0,head);
            tail = body[body.Count-1];
            body.RemoveAt(body.Count - 1);

        }

        /// 
        /// 判定蛇头位置是否有一个食物,如果有,则:
        /// 1.在地图上删除该位置的事物
        /// 2.蛇的身体增长一节
        /// 3.重新生成一个食物
        /// 
        private void Eat()
        {
            Point head = body[0];
            if (Map.Instance().GetAt(head) == Map.Food)
            {
                //1.在地图上删除该位置的事物
                Map.Instance().SetAt(head,Map.Blank);

                //2.蛇的身体增长一节(尾部不删除)
                body.Add(tail);

                //3.重新生成一个食物
                Map.Instance().GenFood();
            }
        }
        public void Update()
        {
            if (IsGameOver())return;
            Turn();
            Move();
            Eat();
        }
        public void Draw()
        {
            for (int i = body.Count-1; i >=0; i--) // j - 列 从蛇尾往蛇头画,防止蛇头被蛇尾覆盖
            {
                Point pt = body[i];
                Console.SetCursorPosition(pt.x * 2, pt.y);
                Console.ForegroundColor = i== 0 ? ConsoleColor.Red : ConsoleColor.Yellow;
                Console.BackgroundColor = ConsoleColor.Gray;
                Console.Write('●');
            }
        }
    }
}

你可能感兴趣的:(C#,C#基类,C#,基类,贪吃蛇)