C# 控制台 贪吃蛇

练手项目,自己想出来的实现方法

 直接上代码

public enum dir //方向枚举
    {
        moveUp,
        moveDown,
        moveLeft,
        moveRight
    }
public class DrawMap //在控制台画二维数组
    {
        //为什么要用静态变量才能打印出蛇? 因为静态变量是在实例化对象之前就有的,对象通过类方法对这个变
        //量的操作会直接改变类里面此静态变量的值 跨类的数据数据互通是时声明为静态变量比较方便

        //二维数组表示地图
        public static string[,] map = new string[10, 10] {
                { "■","■","■","■","■","■","■","■","■","■" },
                { "■","□","□","□","□","□","□","□","□","■" },
                { "■","□","□","□","□","□","□","□","□","■" },
                { "■","□","□","□","□","□","□","□","□","■" },
                { "■","□","□","□","□","□","□","□","□","■" },
                { "■","□","□","□","□","□","□","□","□","■" },
                { "■","□","□","□","□","□","□","□","□","■" },
                { "■","□","□","□","□","□","□","□","□","■" },
                { "■","□","□","□","□","□","□","□","□","■" },
                { "■","■","■","■","■","■","■","■","■","■" },
            };
        public static void Draw()   //画地图
        {
            for (int i = 0; i < map.GetLength(0); i++)
            {
                for (int j = 0; j < map.GetLength(1); j++)
                {
                    Console.Write(map[i, j]);
                }
                Console.WriteLine();
            }
        }
    }

 

public class Food   
    {
        private int foodPos_x;  
        private int foodPos_y;
        public static int[] foodPos = new int[2]; //食物的位置
        public static bool hadFood = false;  //判断地图是否有食物
        Random r = new Random();
        bool isSame;  //判断食物生成的位置是否与蛇身体重合
        private void GetRandomPos()
        {
            foodPos_x = r.Next(1, 8); //生成随机位置
            foodPos_y = r.Next(1, 8);
            foreach (var item in Snake.bodyList)
            {
                if (item[0] == foodPos_x && item[1] == foodPos_y) //食物与身体重合
                {
                    isSame = true;
                    break;
                }
                else
                {
                    isSame = false;
                }
            }
            if (isSame)
            {
                GetRandomPos();  //递归 重新生成
            }
        }
        public static void ClearFood()  //清除食物
        {
            DrawMap.map[foodPos[0], foodPos[1]] = "□";
            hadFood = false;
        }
        public void SetFood() //设置食物
        {
            if (!hadFood)
            {
                GetRandomPos();
                foodPos[0] = foodPos_x;
                foodPos[1] = foodPos_y;
                DrawMap.map[foodPos[0], foodPos[1]] = "★";
                hadFood = true;
            }
        }
    }
public class Input  //检测键盘输入
    {
        public static dir moveDir = dir.moveDown; //运动方向
        public static bool isPlayingGame = true; //判断是否结束游戏
        public static void GetKey() //获取键盘输入值并给运动方向传值
        {
            while (true)
            {
                char key = Console.ReadKey(true).KeyChar;
                if (key == 'd')
                {
                    if (moveDir != dir.moveLeft)
                        moveDir = dir.moveRight;
                }
                else if (key == 'a')
                {
                    if (moveDir != dir.moveRight)
                        moveDir = dir.moveLeft;
                }
                else if (key == 'w')
                {
                    if (moveDir != dir.moveDown)
                        moveDir = dir.moveUp;
                }
                else if (key == 's')
                {
                    if (moveDir != dir.moveUp)
                        moveDir = dir.moveDown;
                }
                else
                {
                    isPlayingGame = false;
                }
            }
        }
    }
public class Snake
    {
        public static List<int[]> bodyList = new List<int[]>(); //身体
        private List<int[]> posList = new List<int[]>(); //记录身体的位置,便于改变身体
        private int[] headNode; //头
        private int[] tailNode; //尾
        private int horizontalPos; //水平位置
        private int verticalPos;   //垂直位置
        private dir moveDir;    //运动方向
        public static int scores; //吃食物获得分数
        public Snake()
        {
            bodyList.Add(new int[] { 5, 4 }); //初始化蛇身体
            bodyList.Add(new int[] { 4, 4 });
            bodyList.Add(new int[] { 3, 4 });
            foreach (var item in bodyList)  //记录蛇身体位置
            {
                posList.Add(item);
            }
            headNode = bodyList[0];
            tailNode = bodyList[bodyList.Count - 1];
            verticalPos = headNode[0];
            horizontalPos = headNode[1];
        }
        public void Move() //实现运动的方法是:移动头,把身体每个位置前移,尾删除。这样只需控制头的位置就可以实现蛇的移动
        {
            moveDir = Input.moveDir; //方向为默认向下
            switch (moveDir) //根据移动方向移动头
            {
                case dir.moveUp:  
                    verticalPos -= 1;
                    headNode = new int[] { verticalPos, horizontalPos };
                    break;
                case dir.moveDown:
                    verticalPos += 1;
                    headNode = new int[] { verticalPos, horizontalPos };
                    break;
                case dir.moveLeft:
                    horizontalPos -= 1;
                    headNode = new int[] { verticalPos, horizontalPos };
                    break;
                case dir.moveRight:
                    horizontalPos += 1;
                    headNode = new int[] { verticalPos, horizontalPos };
                    break;
            }
            if (headNode[0] == 0 || headNode[0] == 9) //判断头是否接触边界
                Input.isPlayingGame = false;
            if (headNode[1] == 0 || headNode[1] == 9) //数组是引用类型,不能用List.Contains();
                Input.isPlayingGame = false;
            foreach (var item in bodyList)  //判断头是否接触身体
            {
                if (headNode[0]==item[0]&&headNode[1]==item[1])
                {
                    Input.isPlayingGame = false;
                    break;
                }
            }
            if (!headNode.SequenceEqual(Food.foodPos)) //如果头没有碰到食物
            {
                bodyList[0] = headNode; //把头点赋值给身体的第一个点
                int r = 0;
                for (int i = 1; i < bodyList.Count; i++) //剩余身体前移
                {
                    bodyList[i] = posList[r];
                    r++;
                }
                posList.Clear();  //清空位置信息
                foreach (var item in bodyList) //重新记录位置信息
                {
                    posList.Add(item);
                    int a = item[0];
                    int b = item[1];
                    DrawMap.map[a, b] = "■"; //修改地图
                }
                DrawMap.map[tailNode[0], tailNode[1]] = "□"; //删除尾部
                tailNode = bodyList[bodyList.Count - 1]; //设置尾节点
            }
            else             //头碰到食物
            { 
                bodyList[0] = headNode;
                Food.ClearFood(); //清除食物
                scores += 1;
                int r = 0;
                for (int i = 1; i < bodyList.Count; i++)
                {
                    bodyList[i] = posList[r];
                    r++;
                }
                bodyList.Add(posList[posList.Count - 1]);
                posList.Clear();
                foreach (var item in bodyList)
                {
                    posList.Add(item);
                    int a = item[0];
                    int b = item[1];
                    DrawMap.map[a, b] = "■";
                }
                tailNode = bodyList[bodyList.Count - 1];
            }
        }
    }
class Program
    {
        static void Main(string[] args)
        {
            Thread getKey = new Thread(Input.GetKey); //用多线程获取玩家输入
            Snake snake = new Snake();
            Food food = new Food();
            getKey.Start();
            getKey.IsBackground = true;  //是后台线程:主进程结束,线程结束
            while (Input.isPlayingGame) //进入游戏
            {
                food.SetFood();   //设置食物
                snake.Move();     //移动蛇
                DrawMap.Draw();   //把map画在控制台
                Thread.Sleep(500);//主线程休眠0.5秒 
                Console.Clear();  //清空控制台
            }
            Console.WriteLine("GameEnd");
            Console.WriteLine($"你的分数是{Snake.scores}");
            Console.ReadKey();
        }
    }

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值