透彻解析Qt入门级项目——贪吃蛇游戏

2023-11-06

1、项目目的:

本项目主要通过编写贪吃蛇游戏来学习,熟悉Qt中封装的类。

2、编译环境

VS2019+Qt5.9

3、功能实现

主要实现下面所列基本功能:

  1. 控制贪吃蛇吃食物
    1. 表示蛇
    2. 控制贪吃蛇上下左右移动
    3. 控制食物的随机分配
    4. 控制蛇的增长  
  2. 暂停游戏
  3. 结束游戏

4、需求分析

4.1、控制贪吃蛇吃食物

4.1.1、表示蛇

贪吃蛇的核心功能就是控制贪吃蛇吃食物,我们很容易可以想到可以用一个个小方块来表示蛇身,那我们应该用什么样的容器来存储这些小方块呢?

蛇的移动我们可以理解为在蛇头处添加一个小方块,在蛇尾处删除掉一个小方块,如下图:

因此会在容器的头部进行插入操作,所以底层数据结构为数组的容器肯定不能选,因为数组的头部插入时间复杂度是o(n),链表就是个非常合适的数据结构,因为它在头部插入的时间复杂度是o(1),所以我们应该选底层数据结构为链表的容器,这里选的是QList,它是Qt中封装的一个类。用该容器存储蛇身后,在构造函数中对其进行初始化,再通过渲染函数将其画在界面里。

//SnakeWidget.h文件
class Snake : public QMainWindow
{
    Q_OBJECT

public:
    Snake(QWidget *parent = nullptr);
    ~Snake();


    private:
    Ui::SnakeClass ui;

    //表示蛇
    QList<QRectF> snake;

    //表示蛇身的小方块的宽高
    int nodeWidth = 20;
    int nodeHeight = 20;


    //渲染(绘图)
    void paintEvent(QPaintEvent* event);

};

4.1.2、控制蛇上下移动

使用QTimer类定义一个定时器,该定时器不断地发出timeout信号,相应的槽函数就会不断地接收该信号来执行动作以控制蛇移动,然后不断地进行重新渲染,以达到蛇不断移动的效果。前面说过蛇的移动实际上是在头部增加一个小方块,在尾部删除一个小方块,因此我们可以封装4个成员函数分别控制蛇在4个方向的头部增加,同时再封装一个成员函数表示尾部的删除。

//SnakeWidget.h文件
class Snake : public QMainWindow
{
    Q_OBJECT

public:
    Snake(QWidget *parent = nullptr);
    ~Snake();


private:
    Ui::SnakeClass ui;

    //表示蛇
    QList<QRectF> snake;

    //表示蛇身的小方块的宽高
    int nodeWidth = 20;
    int nodeHeight = 20;

    //定时器
    QTimer* timer;
    int time = 100;//超时时间间隔,单位毫秒

    //渲染(绘图)
    void paintEvent(QPaintEvent* event);

    //4个成员函数控制蛇4个方向头部的增加
    void addUp();
    void addDown();
    void addLeft();
    void addRight();

    //删除尾部
    void deleteLast();

private slots:
    void timeout();

};

4.1.3、控制食物的随机分配

食物可以用一个小方块来表示,然后封装一个成员函数来随机分配食物这个小方块的位置,先在构造函数中对其进行初始化,最后通过渲染函数将其画在界面中。

//SnakeWidget.h文件
class Snake : public QMainWindow
{
    Q_OBJECT

public:
    Snake(QWidget *parent = nullptr);
    ~Snake();


private:
    Ui::SnakeClass ui;

    //表示蛇
    QList<QRectF> snake;

    //食物
    QRectF food;

    //表示蛇身的小方块的宽高
    int nodeWidth = 20;
    int nodeHeight = 20;


    //渲染(绘图)
    void paintEvent(QPaintEvent* event);

    //4个成员函数控制蛇4个方向的移动
    void addUp();
    void addDown();
    void addLeft();
    void addRight();

    //添加食物
    void addFood();
};

4.1.4、控制蛇的增长

我们只需判断蛇头小方块是否和食物小方块重合,一旦重合,那我们在头部多增加一个小方块,就表示蛇增长了。比如蛇朝右移动,我们在头部增加一个小方块,尾部删除一个小方块,表示蛇的移动,那现在,我们在头部增加两个小方块,在尾部删除一个小方块,就表示蛇增长了。

4.2、暂停游戏

当定时器调用stop()函数时就会停止发送timeout()信号,那么timeout()信号相应的槽函数也就停止执行,timeout()相应的槽函数是控制蛇移动的,timeout相应的槽函数停止执行,那么对应的蛇也就停止了移动,也就呈现出暂停的效果了。

timer->stop();

4.3、结束游戏

可以封装一个成员函数来判断游戏是否结束,这里判断游戏结束的标志就是蛇头碰到蛇身。

bool SnakeWideget::checkContact()
{
	for (int i = 0; i < snake.length(); i++)
	{
		for (int j = i+1;j < snake.length(); j++)
		{
			if (snake[i] == snake[j])
				return true;
		}
	}
	
	return false;
}

2023.2.13更新:新增背景音乐,更换了背景图片,优化了界面

源码链接:Snake · IT大文豪/MyProject - 码云 - 开源中国 (gitee.com)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

透彻解析Qt入门级项目——贪吃蛇游戏 的相关文章

  • 获取 TextBox 中的文本行数

    我试图通过标签显示文本框中的文本行数 但是 问题是如果最后一行为空 标签必须显示没有空行的行号 例如 如果它们有 5 行 最后一行为空 则标签应将行数显示为 4 Thanks private void txt CurrentVinFilte
  • 使用sqlbulkcopy之前如何创建表

    我有一个 DBF 文件 我正在尝试导入该文件 然后将其写入 SQL 表 我遇到的问题是 如果我使用 SqlBulkCopy 它需要我提前创建表 但在我的场景中这是不可能的 因为 dbf 文件不断变化 到目前为止 这是我的代码 public
  • 成员字段、构建顺序

    在 C 中 当执行如下所示的操作时 构造顺序是否得到保证 Logger Logger kFilePath logs runtime log logFile kFilePath 是的 施工顺序始终得到保证 但是 不能保证它与对象在初始值设定项
  • 如何使用最小起订量模拟私有只读 IList 属性

    我试图嘲笑这个列表 private readonly IList
  • 无需登录即可在 Intranet 上获取 Web 应用程序的域\用户名

    我的 Intranet 上有一个 Web 应用程序 VS 2005 有几个页面不需要用户登录应用程序 反馈和默认页面 我正在尝试获取要显示和 或发送反馈的域名和用户名 有没有一种方法可以在不需要用户登录的情况下执行此操作 我试过了this
  • JetBrains Rider 针对 4.5 框架,无法切换到 4.7

    基本上 当尝试添加不支持旧框架的 NuGet 包时 会出现错误 但是在项目配置中只有 4 5 可用 在项目创建过程中 不存在选择目标的选项 有什么方法可以正确配置它吗 I haven t found out how to set up NE
  • 使用 GCHandle 将大型结构数组从 C# unity 脚本传递到 C++ dll 在 C++ 函数执行后崩溃

    我想从 C unity 脚本将结构数组传递给 c 本机插件 我做了如下操作 我可以访问数据 但我的应用程序在执行 c 函数后崩溃 我不知道为什么 C side StructLayout LayoutKind Sequential publi
  • 当 foreach 块的内容具有 Conditional 属性时,C# 编译器是否会对其进行优化?

    我正在工作中编写一些调试代码 我想知道我所做的是否会损害性能 让我们看一下代码 foreach var item in aCollection Debug WriteLine item Name 我知道 Debug 类使用 Conditio
  • 如何检查号码是否只有唯一的数字?

    例如 2345 是唯一的数字 因为没有数字显示两次 但 3324 不是唯一的数字 因为 3 出现了两次 我尝试使用 但我 代码 显示但我没有得到数字我得到了数字 编辑 你不能使用字符串 number 10 number 100 number
  • 使用默认行为将模型绑定到接口

    我正在尝试将控制器操作绑定到接口 但仍保持默认的绑定行为 public class CoolClass ISomeInterface public DoSomething get set ISomeInterface public clas
  • 从二进制文件读取字节到 long int

    我有两个问题 我有二进制文件的数据 我想使用 read 函数读取前 8 个字节以签署 long int 但我不能 你知道我该怎么做吗 如何直接读取一块数据到字符串中 我可以像所示那样阅读吗 前任 ifstream is is open te
  • Web 文本编辑器中的 RTF 格式

    网络上是否有支持 RTF 格式文档输入的文本编辑器 我知道这对 webdev 来说有点奇怪 但我需要从数据库中读取 RTF 文档 并在基于 Web 的文本编辑器中对其进行编辑 然后将其存储回 RTF 中 在我在转换工具上投入太多资金之前 我
  • 重定向 std::cout

    我需要一个类 在其对象的生命周期内将一个 ostream 重定向到另一个 ostream 经过一番修补后 我想出了这个 include
  • 在 Windows 上使用 C/C++ 开发时省略 msvcr100.dll?

    是否可以在 Windows 上使用 C C 进行开发而不链接到 msvcr100 dll 我知道这是 Windows 的标准 c 库 但我想知道如果我没有安装 Visual Studio 或 Redistributable 软件包 我的计算
  • Code::Blocks 中的调试似乎不起作用 - 缺少调试符号

    我正在尝试在 Code Blocks 中调试程序 我跟着本指南 http wiki codeblocks org index php title Debugging with Code Blocks and 这个短视频 http www y
  • 删除数组时出现访问冲突异常

    删除分配的内存时 出现 访问冲突读取位置 异常 如下所示 我有一个针对 Visual Studio 2010 工具集 v100 C 编译器编译的本机 dll 我有一个针对它的托管 dll 包装器 它是针对工具集 v90 编译的 因为我想以
  • 动态菜单创建IoC

    我想知道是否有人知道我如何创建如何使用 AutoFac 之类的东西来让我动态地允许 dll 创建自己的表单和菜单项以在运行时调用它们 所以如果我有一个 员工 dll 新入门表格 证书表格 供应商 dll 供应商详细信息来自 产品形态 在我的
  • 如何使 WinForms UserControl 填充其容器的大小

    我正在尝试创建一个多布局主屏幕应用程序 我在顶部有一些按钮链接到应用程序的主要部分 例如模型中每个实体的管理窗口 单击这些按钮中的任何一个都会在面板中显示关联的用户控件 面板包含用户控件 而用户控件又包含用户界面 WinForms User
  • 如何使用“路径”查询 XDocument?

    我想查询一个XDocument给定路径的对象 例如 path to element I want 但我不知道如何继续 您可以使用以下方法System Xml XPath Extensions http msdn microsoft com
  • 检查另一种形式的线程是否仍在运行

    我有一个涉及两个窗体的 Windows 窗体应用程序 子表单用于将数据导出到 CSV 文件 并使用后台工作者写入文件 当这种情况发生时 我隐藏了表格 当后台工作程序运行时 父窗体仍然处于活动状态 因此即使后台工作程序正在写入文件 用户也可以

随机推荐

  • qt 一个线程接收数据 主线程更新界面 会造成界面退出 怎么解决_打造一个好产品

    原标题 打造一个好产品 让产品自己说话 编辑导语 一个好的产品 关键在于产品经理和团队 产品经理对于产品如何理解以及产品更新迭代时的需求变化 产品如何实现更好的体验等等 本文作者分享了关于产品经理经常犯的七个问题 我们一起来看一下 不管怎么
  • c++双链表【构造函数、运算符重载、析构函数、增删查改及逆置等】

    c 中的双向链表写法 主要实现 增删查改 链表逆置 构造函数 运算符重载 等 建立头文件SList h pragma once typedef int DataType class ListNode friend class List 友元
  • Vue学习-基础篇4

    目录 组件结构讲解 如何在组件中引入其它组件 组件中如何使用外部插件 组件间的传值 Vue cli项目创建 什么是脚手架 创建项目 Vue cli项目结构 Vue cli 入口文件main js分析 组件结构讲解 把每个组件都放到一个独立的
  • 【Shell牛客刷题系列】SHELL28 nginx日志分析6-统计每分钟的请求数

    该系列是基于牛客Shell题库 针对具体题目进行查漏补缺 学习相应的命令 刷题链接 牛客题霸 Shell篇 该系列文章都放到专栏下 专栏链接为 专栏 Shell 欢迎关注专栏 本文知识预告 本文首先学习了sprintf 函数的用法 然后复习
  • python爬虫实战之模拟正方教务系统登录查询成绩

    最近由于某些需要 开始入门Python网络爬虫 想通过一个Python程序来访问正方教务管理系统并且抓取到期末的成绩 由于我并没有深入了解过过其他的编程语言 所以 也比较不出Python和其他语言 如JAVA PHP 的优缺点 只是因为我会
  • JAVA通配符

    上限通配符 我们想要的是一个确切元素类型未知的列表 这一点与数组是不同的 List
  • 一、红外遥控介绍(NEC协议)

    目录 1 1 红外线的介绍 1 2 红外遥控器的工作原理 1 3 NEC协议的介绍 1 引导码的组成 2 地址码 3 数据码 4 反码 5 连发码 1 4 红外接受装置 1 在数码管显示红外解码遥控器的按键值 1 1 红外线的介绍 红外是红
  • Kitti数据集标签中yaw角在不同坐标系的转换

    KITTI数据集中坐标系的定义如下图 相机坐标系 激光雷达坐标系 在标签文件 label 中 最后一个值为物体前进方向与x轴夹角的弧度值 在相机坐标系下 且以顺时针为正 逆时针为负 举个例子 如上图第一个car数据为例 其前进方向与x轴夹角
  • 三、IOC容器原理

    三 IOC容器原理 1 概述 Sun ONE技术体系下的IOC容器有 轻量级的有Spring Guice Pico Container Avalon HiveMind 重量级的有EJB 不轻不重的有JBoss Jdon等等 Spring框架
  • nodejs安装

    CentOS7安装NodeJS 1 官网下载二进制文件 https nodejs org en download 2 下载后上传到目标位置 3 解压包 依次执行 cd soft nodejs xz d node v12 18 2 linux
  • Python3 + xpath + excel 实现对boss直聘网的爬取

    一 项目简介 1 内容 抓取boss直聘网上广州地区的 python 相关工作的招聘信息 并且将招聘信息循环保存在excel表中 2 目标网站 https www zhipin com c101280100 query python pag
  • Linux中用gdb 查看代码堆栈的信息

    core dump 一般是在segmentation fault 段错误 的情况下产生的文件 需要通过ulimit来设置才会得到的 调试的话输入 gdb filename core filename就是产生core文件的可执行文件 core
  • Windows server 远程桌面连接用户不活动自动注销配置

    Windows server 远程桌面连接用户不活动自动注销配置
  • VMware三种网络模式配置详解。

    VMware网络 本质上不会配置VMware网络 是因为对其不够熟悉 VMware提供了三种可靠的网络模式 我相信只要了解了他们的区别 配置起来应该是如鱼得水的 如果还在为你的虚拟机上不了网而发愁 那么请跟随我的脚步 让我们来探究他们到底有
  • Flowable 用户问题

    Flowable用户和系统用户问题 springboot集成flowable modeler 实现免登 权限管理 Flowable引擎使用统一权限管理
  • 《信号与系统》解读 第4章 连续信号的离散化:采样与采样定理、奈奎斯特准则、脉冲编码调制PCM

    前言 如果你对采样定理和奈奎斯特准则一知半解 本文将给茅塞顿开 如果你对为什么采样频率必须大于等于原始信号的带宽的2倍 本文将给你答案 目录 1 信号与系统的模型 2 为什么要对连续信号离散化 3 连续信号离散化 采样 的模型 3 1 采样
  • 使用Hexo搭建博客并部署到Github

    一 博客环境搭建 Hexo 是一个静态博客框架 基于 Node js 将 Markdown 文章通过渲染引擎 生成一个静态网页 再结合 Git 命令 ssh Hexo 是一个快速 简洁且高效的博客框架 Hexo 使用 Markdown 或其
  • 深入理解 Java 垃圾回收机制

    一 垃圾回收机制的意义 java 语言中一个显著的特点就是引入了java回收机制 是c 程序员最头疼的内存管理的问题迎刃而解 它使得java程序员在编写程序的时候不在考虑内存管理 由于有个垃圾回收机制 java中的额对象不在有 作用域 的概
  • 解决Excel打开UTF-8编码的CSV文件乱码的问题

    解决Excel打开UTF 8编码的CSV文件乱码的问题 引用自 https en wikipedia org wiki Comma separated values CSV formats are not limited to a part
  • 透彻解析Qt入门级项目——贪吃蛇游戏

    1 项目目的 本项目主要通过编写贪吃蛇游戏来学习 熟悉Qt中封装的类 2 编译环境 VS2019 Qt5 9 3 功能实现 主要实现下面所列基本功能 控制贪吃蛇吃食物 表示蛇 控制贪吃蛇上下左右移动 控制食物的随机分配 控制蛇的增长 暂停游