导读:本期聚焦于小伙伴创作的《如何用C#从零实现一个贪吃蛇游戏?核心代码逻辑详解》,敬请观看详情。控制台里跑起来的贪吃蛇其实藏着不少有意思的逻辑。最核心的是用二维数组或坐标列表维护蛇身,再用定时器驱动移动。很多人写第一版时把食物生成和碰撞检测混在一起,导致蛇穿墙还能吃自己。本文把方向控制、身体增长、死亡判定拆开讲,结合一段可直接编译的C#示例,说明如何用Queue或List管理节点、怎样在每一步刷新时只重绘变化区域。理清这些,你就能把基础版本改造成带计分和加速的完整体。

用C#写贪吃蛇是练习面向对象和基础数据结构的经典入门项目。它不需要任何第三方游戏引擎,依靠控制台或者简单的WinForms界面就能跑起来。整个游戏的本质,就是在一个固定大小的网格里,控制一条由若干节点组成的蛇不断移动、吃食物、变长,同时避免撞墙或撞到自己。

如何用C#从零实现一个贪吃蛇游戏?核心代码逻辑详解

一、游戏核心模型设计

贪吃蛇的游戏状态可以拆成三个部分:蛇本身、食物、以及游戏边界。蛇最好用有序的坐标集合来表达,头部在集合开头,尾部在末尾。每次移动时,根据当前方向在头部前面插入一个新坐标,如果没吃到食物就把尾部坐标删掉,这样蛇就“前进”了。用List<Point>或者Queue<Point>都能实现,List更方便随机访问做碰撞检测,Queue则天然符合先进先出的身体滑动逻辑。

食物就是一个随机生成在空白格子里的坐标。边界通常就是控制台窗口的宽高,或者自己定义的二维数组大小。下面这段代码展示了如何用List<Point>定义蛇与食物,以及基本的初始化方式。

using System;
using System.Collections.Generic;

class SnakeGame
{
    // 用List保存蛇身,index 0是头
    private List<Point> snake = new List<Point>();
    private Point food;
    private int width = 20;
    private int height = 10;

    public void Init()
    {
        // 初始蛇长度为3,横向放在中间
        snake.Add(new Point(5, 5));
        snake.Add(new Point(4, 5));
        snake.Add(new Point(3, 5));
        GenerateFood();
    }

    // 在空白位置随机生成食物
    private void GenerateFood()
    {
        Random rnd = new Random();
        do
        {
            food = new Point(rnd.Next(0, width), rnd.Next(0, height));
        } while (snake.Contains(food));
    }
}

二、移动与方向控制逻辑

方向控制是贪吃蛇里最容易出bug的地方。常见错误是允许玩家直接反向,比如蛇往右走时马上按左键,结果头直接撞到第二节身体。正确做法是记录一个“当前方向”枚举,并且只接受与原方向不相反的新方向输入。在每一步Tick里,根据方向算出新的头部坐标。

移动的核心步骤是:计算新头坐标,插入到List开头,判断是否吃到食物,没吃到就移除末尾。这样无论蛇多长,每一步只是增减一个节点,时间复杂度是O(1)级别(Contains判断食物除外)。下面示例展示了移动方法和方向枚举的配合。

enum Direction { Up, Down, Left, Right }

class SnakeGame
{
    private Direction dir = Direction.Right;

    public void ChangeDirection(Direction newDir)
    {
        // 禁止180度反向
        if (dir == Direction.Left && newDir == Direction.Right) return;
        if (dir == Direction.Right && newDir == Direction.Left) return;
        if (dir == Direction.Up && newDir == Direction.Down) return;
        if (dir == Direction.Down && newDir == Direction.Up) return;
        dir = newDir;
    }

    public void Move()
    {
        Point head = snake[0];
        Point newHead = head;
        if (dir == Direction.Right) newHead.X++;
        else if (dir == Direction.Left) newHead.X--;
        else if (dir == Direction.Up) newHead.Y--;
        else if (dir == Direction.Down) newHead.Y++;

        snake.Insert(0, newHead);
        if (newHead.Equals(food))
        {
            GenerateFood(); // 吃到食物,不删尾,蛇变长
        }
        else
        {
            snake.RemoveAt(snake.Count - 1);
        }
    }
}

三、碰撞检测与游戏结束判定

碰撞分为两种:撞墙和撞自己。撞墙很好判断,只要新头坐标的X小于0、大于等于width,或者Y小于0、大于等于height,就结束游戏。撞自己则是检查新头坐标是否出现在snake集合里(注意要排除还没移除的旧尾,不过上面先插入再决定是否删尾的逻辑已经自然规避了这个问题)。

把检测逻辑放在Move之后调用最合适。一旦返回true表示游戏结束,主循环就可以跳出并输出分数。下面给出具体检测方法,以及简单的控制台主循环示例。

class SnakeGame
{
    public bool CheckCollision()
    {
        Point head = snake[0];
        // 撞墙
        if (head.X < 0 || head.X >= width || head.Y < 0 || head.Y >= height)
            return true;
        // 撞自己(从第二节开始比)
        for (int i = 1; i < snake.Count; i++)
        {
            if (snake[i].Equals(head))
                return true;
        }
        return false;
    }
}

class Program
{
    static void Main()
    {
        SnakeGame game = new SnakeGame();
        game.Init();
        while (true)
        {
            // 这里省略了键盘读取和方向变更代码
            game.Move();
            if (game.CheckCollision())
            {
                Console.WriteLine("游戏结束,长度:" + game.GetLength());
                break;
            }
            System.Threading.Thread.Sleep(200);
        }
    }
}

四、渲染与体验优化思路

控制台版本可以用Console.SetCursorPosition把光标移到对应坐标,用不同字符画蛇头和蛇身,比每次清屏重画效率更高,也避免闪烁。如果迁移到WinForms,可以用Panel的Paint事件配合Timer,用FillRectangle画格子。食物用红色,蛇头用亮绿,身体用深绿,视觉上一眼就能分清。

进阶玩法包括:随分数提高缩短Timer间隔实现加速、记录最高分、增加障碍物层。这些都不改变上面说的核心模型,只是在Move和生成食物时多一层判断。理解了List管理蛇身、方向锁、双类型碰撞检测这三块,你写的C#贪吃蛇就已经具备可玩性,后续扩展只是堆功能而已。

C#贪吃蛇游戏开发修改时间:2026-08-04 03:51:27

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。