【c# 控制台贪吃蛇教程】因为减脂所以贪吃啥来了

前言

        一觉睡醒,发现自己要励志做个健美男,下决心从减脂开始,不能久坐台中,脑中计划出500条减脂计划,本着有想法就实践,抱着凡是重在参与不及结果的脑子,首先写个贪吃啥,立证自己的减脂决心。

        项目教程完全小白化,大神不用瞄了,本项目有源码下载。


目录

一、准备工作

       1.1、创建控制台应用

       1.2、创建类

       1.3、声明全部变量

       1.4、点阵字体

二、主要功能函数

        2.1、蛇的操作

        2.2、地图和围墙

        2.3、生成食物

        2.4、吃到食物

        2.5、吃到自己

        2.6、撞到墙

        2.7、控制蛇

        2.8、十进制显示

三、运行图示

四、总结

五、工程下载地址  


一、准备工作

       1.1、创建控制台应用

        打开vs2022,创建一个控制台应用,如图


       1.2、创建类

        项目中右键,弹出框后选择创建一个类

        类名就叫 tanchisha,如果你创建得类有其他内容,都清空,直接复制下面的内容

using System.Data;

static class Tanchisha
{

}

       1.3、声明全部变量
    //蛇体字符
    static string snakeString = "o";
    //墙字符
    static string wallString = "█";
    //食物字符
    static string foodString = "*";
    //行
    static int row = 20;
    //列
    static int column = 50;
    //地图二维坐标
    static List<List<int>> mapList = new List<List<int>>();
    //食物坐标
    static List<int> foodPoint = new List<int>();
    //蛇点集合
    static List<List<int>> snakePointsList = new List<List<int>>();
    //移动速度
    static int moveBasicSpd = 100;
    //移动速度
    static int moveSpdLV = 2;
    //是否死亡
    static bool isLive = true;
    //十进制计数(点阵字体,因每个格子表示一个数字的特性,如果不自己设计十进制计数,会出现计数错乱显示的问题)
    static List<int> movecountList = new List<int>() { 0, 0, 0, 0 };
    static List<int> eatcountList = new List<int>() { 0, 0, 0, 0 };

        上面的方块是长方形(string wallString = "█";),显示在控制台很难看,没关系,接着要调整控制台的字体显示


       1.4、点阵字体

        右键控制台

        选择点阵字体,因为点阵字体是实实在在的正方形矩阵,这样可以把它看成像素点。这样整个游戏视觉会规正很多。

        也是这样原因,数字的显示要自己写十进制计数

        (点阵字体,因每个格子显示一个数字的特性,如果不自己设计十进制计数,会出现计数错乱显示的问题


二、主要功能函数

        2.1、蛇的操作

             创建按键枚举,枚举分类,方便判断

    enum Dirction
    {
        D_up,
        S_down,
        A_left,
        D_right
    }

           按键判断

    //键盘操作
    static void KeyCtrl()
    {
        while (true)
        {
            switch (Console.ReadKey().Key)
            {
                case ConsoleKey.UpArrow:
                    SnakeDirction(Dirction.S_down, Dirction.D_up);
                    break;
                case ConsoleKey.DownArrow:
                    SnakeDirction(Dirction.D_up, Dirction.S_down);
                    break;
                case ConsoleKey.LeftArrow:
                    SnakeDirction(Dirction.D_right, Dirction.A_left);
                    break;
                case ConsoleKey.RightArrow:
                    SnakeDirction(Dirction.A_left, Dirction.D_right);
                    break;
                default:
                    break;
            }
        }
    }

        禁止蛇掉头

    static void SnakeDirction(Dirction d1, Dirction d2)
    {
        curDirction = curDirction != d1 ? d2 : d1;
    }

        2.2、地图和围墙

        为可以行动区间,为不可行动区间。

    static void CreateMap()
    {
        for (int i = 0; i < row; i++)
        {
            List<int> temp = new List<int>();
            for (int j = 0; j < column; j++)
            {
                if (i % (row - 1) == 0 || j % (column - 1) == 0)
                    temp.Add(1);
                else
                    temp.Add(0);
            }
            mapList.Add(temp);
        }
    }

         i % (row - 1) i 等于 0 或者 i 等于row - 1时,表示左右的围墙

         j % (column - 1) 等于 0 或者 i 等于column - 1时,表示上下的围墙

这样上下左右都被墙裹上了。

        //清屏幕
        Console.Clear();
        // 光标不可见
        Console.CursorVisible = false;
        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < column; j++)
            {
                if (mapList[i][j] == 0) continue;
                SetString(ConsoleColor.Red, j, i, wallString);
            }
        }

        2.3、生成食物

        生成食物要确保两点

  •    食物不能生成在围墙上
  •    食物不能生成在蛇的身上
    static void CreateFood()
    {
        //先将蛇占用的格子取出
        List<List<int>> tempList = new List<List<int>>(mapList);
        for (int i = 0; i < mapList.Count; i++)
        {
            for (int j = 0; j < mapList[i].Count; j++)
            {
                List<int> ijlist = new List<int>() { i, j };
                foreach (List<int> innerList in snakePointsList)
                {

                    if (innerList.SequenceEqual(ijlist))
                    {
                        tempList[i][j] = 1;
                        break;
                    }
                }
            }
        }
        //再随机取出非1的地图二维序列,该点阵坐标是食物的生成坐标
        var tempElements = tempList.Select((sublist, rowIndex) => new { sublist, rowIndex })
                                        .SelectMany(x => x.sublist.Select((value, colIndex) => new { x.rowIndex, colIndex, value }))
                                        .Where(x => x.value != 1);
        var randomElement = tempElements.ElementAt(new Random().Next(tempElements.Count()));
        int x = randomElement.colIndex; // 行索引
        int y = randomElement.rowIndex; // 列索引
        foodPoint = new List<int> { x, y };
        SetString(ConsoleColor.Yellow, foodPoint[0], foodPoint[1], foodString);
    }

        分别对应的方法是:

  •     在整个二维地图数组中,先将蛇占用的地图坐标临时赋值为1,这样得到一个临时新地图二维数据
  •     再随机取出元素值非1的临时地图二维序列,该点阵坐标是食物的生成坐标

        2.4、吃到食物
    static void EatFood(int x, int y)
    {
        if (x == foodPoint[1] && y == foodPoint[0])
        {
            snakePointsList.Add(new List<int> { snakePointsList[snakePointsList.Count - 1][1], snakePointsList[snakePointsList.Count - 1][0] });
            DecimalismNum(eatcountList, "吃食物:", ConsoleColor.Yellow, 15, row + 1, 24);
            CreateFood();
        }
    }

        吃到食物,将食物坐标加入到蛇的坐标中


        2.5、吃到自己
    static void HitSelf(int x, int y)
    {
        if (snakePointsList.Where(point => point[0] == x && point[1] == y).Any())
        {
            isLive = false;
            Console.SetCursorPosition(column / 2 - 4, row / 2 - 2);
            Console.Write("游戏结束");
        }
    }

        吃到自己后,在荧幕中央显示结束语,并且将  isLive = false;

         isLive 负责跳出游戏的进程,终止游戏进度。

        同理,蛇撞到墙效果一样。


        2.6、撞到墙
    static void HitWall(int x, int y)
    {
        if (x >= row || y >= column || x < 0 || y < 0)
        {
            isLive = false;
            Console.SetCursorPosition(column / 2 - 4, row / 2 - 2);
            Console.Write("游戏结束");
        }
    }

        2.7、控制蛇

        操作键盘的上下左右,控制蛇,蛇按照方向进行坐标位移,并获取唯一点阵坐标加入到蛇坐标,同时清除蛇的后坐标,刷新画面

 static void CreateSnake(int x, int y)
 {
     string snkStr = string.Empty;
     Task.Run(() =>
     {
         snakePointsList.Add(new List<int>() { x, y });
         while (true)
         {
             switch (curDirction)
             {
                 case Dirction.D_right:
                     y++;
                     break;
                 case Dirction.A_left:
                     y--;
                     break;
                 case Dirction.S_down:
                     x++;
                     break;
                 case Dirction.D_up:
                     x--;
                     break;
             }
             HitSelf(x, y);
             HitWall(x, y);
             if (isLive == false) break;//不把isLive放到while循环条件,放这里可以蛇死亡后跳出循环,不会出现延迟效果
             DecimalismNum(movecountList, "步数:", ConsoleColor.Yellow, 1, row + 1, 8);
             Refesh(x, y);
             Thread.Sleep(moveBasicSpd * moveSpdLV);
             //Task.Delay(moveBasicSpd * moveSpdLV).Wait(); // 不要用Task.Delay
             EatFood(x, y);

         }
     });
 }


        2.8、十进制显示

        前面说了,点阵字体显示数字占据一个格子,多位数计数显示会出现错乱,所以写一个十进制,计数到千位。如果想计数到更多,自己添加。

static void DecimalismNum(List<int> list, string title, ConsoleColor color, int tx, int ty,int nx)
{
    list[0] += 1;
    if (list[0] % 10 == 0)
    {
        list[0] = 0;
        list[1] += 1;
        if (list[1] % 10 == 0)
        {
            list[1] = 0;
            list[2] += 1;
            if (list[2] % 10 == 0)
            {
                list[2] = 0;
                list[3] += 1;
            }
        }
    }
    
    SetString(color, tx, ty, title);
    Console.SetCursorPosition(nx, row + 1);
    Console.Write(list[3].ToString("#"));

    Console.SetCursorPosition(nx + 1, row + 1);
    Console.Write(list[2].ToString(list[3] > 0 ? list[1].ToString() : "#"));

    Console.SetCursorPosition(nx + 2, row + 1);
    Console.Write(list[1].ToString(list[2] > 0 ? list[1].ToString() : "#"));

    Console.SetCursorPosition(nx + 3, row + 1);
    Console.Write(list[0].ToString());
}

        这样就能解决,步数,分数等计数问题了。


三、运行图示


四、总结

  •    Task.Run(() =>  while (true) {  内容  } }); 是游戏的动画功能模块
  •    Thread.Sleep() 和 Task.Delay 都有延时执行的功能,但在项目中Thread.Sleep效果更好
  •    很多奇特的,特殊的字符,控制台并不会显示。控制台只适合熟悉编程思路。
  •    点阵字体8x8是目前唯一的正方形格子,只能显示一个字符,最好二进制自己写

写着写着就这么多了,可能不是特别全,不介意费时就看看吧。有时间还会接着更新。


五、工程下载地址  

【c#控制台贪吃蛇】工程下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学与用

原创作者,在线要饭

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值