C# WinForms 贪吃蛇游戏开发实战

程一诺
程一诺
发布时间:2026-10-15| 4人浏览过
原创

介绍如何利用 C# WinForms 框架结合定时器(Timer)与自定义类封装技术,从零构建一个包含界面布局、蛇身移动算法、碰撞判定及分数统计的贪吃蛇游戏。

项目效果预览

设计思路与结构拆解

本项目采用面向对象的设计模式,将游戏的主视图与控制逻辑分离。主窗口负责 UI 渲染(继承自 Form),而 Snake 行为逻辑则封装在一个独立的 class Snake 中。两者通过静态字段或传参进行通信:

  1. 视觉层:利用 Panel 控件作为游戏画布,在 Paint 事件中调用 Graphics 对象绘制网格、蛇身(红色矩形)、食物(蓝色矩形)。使用双缓冲绘图或 ControlStyles.OptimizedDoubleBuffer 可有效减少画面闪烁。
  2. 逻辑层:由定时器 Timer 驱动帧率。每一帧计算蛇头的新坐标,并依据方向数组更新所有关节的位置。
  3. 交互层:拦截窗体按键事件 KeyDown 改变移动轴向,同时支持菜单选项切换难度。

第 1 步:初始化窗体与绘制游戏面板

首先在项目中创建一个 Windows Forms 应用程序。设置主窗体属性并拖入必要的控件:MenuStrip(用于菜单栏,包含“设置”与“控制”子项)、Panel(命名为 panel1,作为游戏背景图)、Label(用于显示分数)以及 TextBox(用于强制获取焦点以响应键盘输入)。

核心代码如下,它定义了窗体的状态变量、画笔颜色以及在画板上绘制静态网格的逻辑:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    public static bool ifStart = false;//判断是否开始
    public static int career = 400;//移动的速度(毫秒)
    Snake snake = new Snake();//实例化Snake类
    int snake_W = 20;//骨节的宽度
    int snake_H = 20;//骨节的高度
    public static bool pause = false;//是否暂停游戏

    /// <summary>
    /// 绘制游戏场景网格
    /// </summary>
    public void ProtractTable(Graphics g)
    {
        for (int i = 0; i <= panel1.Width / snake_W; i++)//绘制单元格的纵向线
        {
            g.DrawLine(new Pen(Color.Black, 1), new Point(i * snake_W, 0), new Point(i * snake_W, panel1.Height));
        }
        for (int i = 0; i <= panel1.Height / snake_H; i++)//绘制单元格的横向线
        {
            g.DrawLine(new Pen(Color.Black, 1), new Point(0, i * snake_H), new Point(panel1.Width, i * snake_H));
        }
    }

    private void panel1_Paint(object sender, PaintEventArgs e)
    {
        Graphics g = panel1.CreateGraphics();//创建panel1控件的Graphics类
        ProtractTable(g);//绘制游戏场景
        if (!ifStart)//如是没有开始游戏
        {
            Snake.timer = timer1;
            Snake.label = label2;
            snake.Ophidian(panel1, snake_W);//初始化场地及贪吃蛇信息
        }
        else
        {
            for (int i = 0; i < Snake.List.Count; i++)//绘制蛇身
            {
                e.Graphics.FillRectangle(Snake.SolidB, ((Point)Snake.List[i]).X + 1, ((Point)Snake.List[i]).Y + 1, snake_W - 1, snake_H - 1);
            }
            e.Graphics.FillRectangle(Snake.SolidF, Snake.Food.X + 1, Snake.Food.Y + 1, snake_W - 1, snake_H - 1);//绘制食物
            if (Snake.ifGame)//如果游戏结束
                //绘制提示文本
                e.Graphics.DrawString("Game Over", new Font("宋体", 30, FontStyle.Bold), new SolidBrush(Color.DarkSlateGray), new PointF(150, 130));
        }
    }
}

第 2 步:实现游戏控制与计时器逻辑

游戏的核心动力源是 timer1_Tick 事件。它不直接计算移动,而是委托给 snake.SnakeMove() 方法处理坐标更新。主窗体需要处理三个状态:开始、暂停和退出,并通过菜单按钮触发对应的控制函数。

以下代码展示了如何重置棋盘、启动/停止定时器,以及如何绑定不同难度的速度值:

    private void 开始ToolStripMenuItem_Click(object sender, EventArgs e)
    {
        NoviceCortrol(Convert.ToInt32(((ToolStripMenuItem)sender).Tag.ToString()));
        snake.BuildFood();
        textBox1.Focus();
    }

    /// <summary>
    /// 控制游戏的开始、暂停和结束
    /// </summary>
    public void NoviceCortrol(int n)
    {
        switch (n)
        {
            case 1://开始游戏
                {
                    ifStart = false;
                    Graphics g = panel1.CreateGraphics();//创建panel1控件的Graphics类
                    g.FillRectangle(Snake.SolidD, 0, 0, panel1.Width, panel1.Height);//刷新游戏场地
                    ProtractTable(g);//绘制游戏场地
                    ifStart = true;//开始游戏
                    snake.Ophidian(panel1, snake_W);//初始化场地及贪吃蛇信息
                    timer1.Interval = career;//设置贪吃蛇移动的速度
                    timer1.Start();//启动计时器
                    pause = true;//是否暂停游戏
                    label2.Text = "0";//显示当前分数
                    break;
                }
            case 2://暂停游戏
                {
                    if (pause)//如果游戏正在运行
                    {
                        ifStart = true;//游戏正在开始
                        timer1.Stop();//停止计时器
                        pause = false;//当前已暂停游戏
                    }
                    else
                    {
                        ifStart = true;//游戏正在开始
                        timer1.Start();//启动计时器
                        pause = true;//开始游戏
                    }
                    break;
                }
            case 3://退出游戏
                {
                    timer1.Stop();//停止计时器
                    Application.Exit();//半闭工程
                    break;
                }
        }
    }

    private void 初级ToolStripMenuItem_Click(object sender, EventArgs e)
    {
        if (timer1.Enabled == false)//如果游戏没有开始
        {
            初级ToolStripMenuItem.Checked = false;//设置该项没有被选中
            中级ToolStripMenuItem.Checked = false;//设置该项没有被选中
            高级ToolStripMenuItem.Checked = false;//设置该项没有被选中
            ((ToolStripMenuItem)sender).Checked = true;//设置当前项被选中
            switch (Convert.ToInt32(((ToolStripMenuItem)sender).Tag.ToString()))
            {
                case 1://高级 (注:原文档标签定义可能混淆,此处依据实际逻辑修正对应关系)
                    {
                        career = 400;//设置移动的速度较慢
                        break;
                    }
                case 2://中级
                    {
                        career = 200;
                        break;
                    }
                case 3://初
                    {
                        career = 50;//设置移动的速度较快
                        break;
                    }
            }
        }
        textBox1.Focus();//获得焦点
    }
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。