基于C++的QT实现贪吃蛇小游戏
文章目录:
一:效果演示
二:实现思路
三:代码实现
widget.h
widget.cpp
main.cpp
一:效果演示
效果图◕‿◕✌✌✌
代码下载
二:实现思路
通过按键控制蛇的移动,每吃一个商品蛇身就会加长,如果蛇身头尾相碰就结束游戏
声明渲染绘图:画笔画刷进行相关的渲染背景蛇和奖品 按键处理机制:方便后面的键盘操作定时器:到时就会触发按下空格:代表开始上下左右键控制蛇的移动方向:DIR_DOWN DIR_UP DIR_LEFT DIR_RIGHT蛇:蛇的表示:矩形的两点确定小方块,3个小方块为初始蛇身判断蛇身蛇头:如果蛇头蛇尾接触就结束游戏蛇身变动:相交就吃掉奖品,吃一个加一个小方块奖品奖品的表示:小红点奖品的添加:蛇吃完一个奖品就马上随机添加一个奖品蛇吃奖品:吃一个奖品会加一个方块:上面、下面、左面、右面
三:代码实现
widget.h
#ifndef WIDGET_H #define WIDGET_H#include <QWidget> //按键 #include <QKeyEvent> //定时器 #include <QTimer>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE//定义方向 enum Dirct{DIR_LEFT,DIR_RIGHT,DIR_DOWN,DIR_UP};class Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();protected://声明渲染绘图void paintEvent(QPaintEvent *event);//声明按键处理void keyPressEvent(QKeyEvent *event);//声明上面加一个函数void addTop();//声明下面加一个函数void addDown();//声明左面加一个函数void addLeft();//声明右面加一个函数void addRight();//声明减去一个模块void deleteLast();//声明添加奖品函数void addNewReword();//声明判断蛇头蛇身bool checkContact();private:Ui::Widget *ui;//初始化定义方向int moveFlag = DIR_UP;//定义启动的开始bool gameStart = false;//定义定时器QTimer *timer;int time = 100;//超时事件间隔(毫秒)//蛇的表示 矩形两点确定(容器)QList <QRectF> snake;//小方块表示int nodeWidth = 20;int nodeHeight = 20;//奖品的表示QRectF rewardNode;protected slots://定义超时函数void timeout(); };#endif // WIDGET_H
widget.cpp
#include "widget.h" #include "ui_widget.h" #include <qmediaplayer.h>//画家 #include <QPainter> //文字 #include <QRandomGenerator> //背景音乐 #include <QtMultimedia/QtMultimedia> #include <QtMultimediaWidgets/QVideoWidget> #include <QApplication> #include <QMediaPlayer> #include <QUrl> #include <QFileDialog>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//定义窗口大小//resize(800,600);this->setFixedSize(800,600);QMediaPlayer *player = new QMediaPlayer;player->setSource(QUrl::fromLocalFile("F:/QT/Snake/images/mu.mp3"));player->play();//实现定时器 可以让蛇动起来//创建定时器timer = new QTimer();//信号槽 timeout超时connect(timer,SIGNAL(timeout()),this,SLOT(timeout()));//初始化蛇身QRectF rect(400,300,nodeWidth,nodeHeight);//小方块加到蛇身上去snake.append(rect);//再加两端addTop();addTop();//初始化奖品addNewReword();//背景音乐 // //创建一个显示视频的控件 // QVideoWidget* videowin = new QVideoWidget(this); // videowin->resize(400,300); // //添加一个播放器 // QMediaPlayer *player = new QMediaPlayer(this); // player->setVideoOutput(videowin); // //音乐 // player->setMedia(QMediaContent(QUrl::fromLocalFile("F:/QT/Snake/images/game.mp3"))); // //player->setVolume(50);//音量 // //开始播放 // player->play();}Widget::~Widget() {delete ui; }//实现按键函数 控制方向 void Widget::keyPressEvent(QKeyEvent *event){switch (event->key()) {case Qt::Key_Up:if(moveFlag != DIR_DOWN){moveFlag = DIR_UP;}break;case Qt::Key_Down:if(moveFlag != DIR_UP){moveFlag = DIR_DOWN;}break;case Qt::Key_Right:if(moveFlag != DIR_LEFT){moveFlag = DIR_RIGHT;}break;case Qt::Key_Left:if(moveFlag != DIR_RIGHT){moveFlag = DIR_LEFT;}break;case Qt::Key_Space:if(gameStart == false){gameStart = true;//启动定时器timer->start(time);}else{gameStart = false;//停止定时器timer->stop();}break;default:break;} }//实现超时函数 void Widget::timeout(){//实现逻辑要么都上移,要么底部加一个,顶部取消一个//判断有没有重合int count = 1;if(snake[0].intersects(rewardNode)){//相交就吃掉奖品count++;//吃掉添加新的奖品addNewReword();}while (count--) {//蛇的移动switch (moveFlag) {case DIR_UP:addTop();break;case DIR_DOWN:addDown();break;case DIR_LEFT:addLeft();break;case DIR_RIGHT:addRight();break;default:break;}}//删除一个deleteLast();//刷新一下update();}//实现上面加一个函数 void Widget::addTop(){QPointF leftTop;QPointF rightBotom;//超出边界(顶端) 加到最下面if(snake[0].y()-nodeHeight < 0){//this->height窗口leftTop = QPoint(snake[0].x(),this->height()-nodeHeight);rightBotom = QPointF(snake[0].x()+nodeWidth,this->height());}else{//没有超出的情况//在蛇的上面(蛇和矩形)//左上角坐标 nodeHeight小方块矩形leftTop = QPointF(snake[0].x(),snake[0].y()-nodeHeight);//右下角坐标rightBotom = snake[0].topRight();}//加一个小方块snake.insert(0,QRectF(leftTop,rightBotom)); }//实现下面加一个函数 void Widget::addDown(){QPointF leftTop;QPointF rightBotom;//超出边界(顶端) 加到最下面if(snake[0].y()+nodeHeight*2 > this->height()){leftTop = QPointF(snake[0].x(),0);rightBotom = QPointF(snake[0].x()+nodeWidth,nodeHeight);}else{//没有超出的情况//在蛇的上面(蛇和矩形)//左上角坐标 nodeHeight小方块矩形leftTop = snake[0].bottomLeft();//右下角坐标rightBotom = snake[0].bottomRight()+QPointF(0,nodeHeight);}//加一个小方块snake.insert(0,QRectF(leftTop,rightBotom)); }//实现左面加一个函数 void Widget::addLeft(){QPointF leftTop;QPointF rightBotom;//超出边界(顶端) 加到最下面if(snake[0].x()-nodeWidth < 0){leftTop = QPointF(this->width()-nodeWidth,snake[0].y());}else{//没有超出的情况//在蛇的上面(蛇和矩形)//左上角坐标 nodeHeight小方块矩形leftTop = snake[0].topLeft()-QPointF(nodeWidth,0);}rightBotom = leftTop+QPointF(nodeWidth,nodeHeight);//右下角坐标//加一个小方块snake.insert(0,QRectF(leftTop,rightBotom)); }//实现右面加一个函数 void Widget::addRight(){QPointF leftTop;QPointF rightBotom;//超出边界(顶端) 加到最下面if(snake[0].x()-nodeWidth*2 > this->width()){leftTop = QPointF(0,snake[0].y());}else{//没有超出的情况//在蛇的上面(蛇和矩形)//左上角坐标 nodeHeight小方块矩形leftTop = snake[0].topRight();}rightBotom = leftTop+QPointF(nodeWidth,nodeHeight);//右下角坐标//加一个小方块snake.insert(0,QRectF(leftTop,rightBotom)); }//实现绘图 void Widget::paintEvent(QPaintEvent *event){//画家QPainter painter(this);//画笔QPen pen;//画刷QBrush brush;//背景图片QPixmap pix;pix.load("F:/QT/Snake/images/bk.png");// QPixmap pixmap(":/images/bk.png");painter.drawPixmap(0,0,800,600,pix);//画蛇//画笔pen.setColor(Qt::black);//画刷brush.setColor(Qt::darkMagenta);brush.setStyle(Qt::SolidPattern);//画家使用画笔和画刷painter.setPen(pen);painter.setBrush(brush);//画蛇的头尾for(int i=0;i<snake.length();i++){painter.drawRect(snake[i]);}//画奖品//画笔pen.setColor(Qt::red);//画刷brush.setColor(Qt::red);brush.setStyle(Qt::SolidPattern);//画家使用画笔和画刷painter.setPen(pen);painter.setBrush(brush);//painter.drawRect(rewardNode);//奖品painter.drawEllipse(rewardNode);//判断蛇头是否碰到蛇身if(checkContact()){QFont font("方块输出",30,QFont::ExtraLight,false);painter.setFont(font);painter.drawText((this->width()-300)/2,(this->height()-30)/2,QString("完成"));timer->stop();}//调用一下父类QWidget::paintEvent(event); }//实现减去一个方块 void Widget::deleteLast(){snake.removeLast(); }//实现添加奖品函数 void Widget::addNewReword(){//奖品int width = this->width();int a = QRandomGenerator::global()->bounded(width/20*20);int height = this->height();int b = QRandomGenerator::global()->bounded(height/20*20);rewardNode = QRectF(//qrand()%(this->width()/20)*20,//qrand()%(this->height()/20)*20,//QT6用上面方法会报错:'qrand' was not declared in this scope; did you mean 'srand'?a,b,nodeWidth,nodeHeight); }//实现判断蛇头是否碰到蛇身函数 bool Widget::checkContact(){for(int i = 1; i < snake.length(); i++)for (int j = i+1; j < snake.length(); j++) {if(snake[i] == snake[j]){return true;}}return false; }
main.cpp
#include "widget.h"#include <QApplication> #include <QLocale> #include <QTranslator>int main(int argc, char *argv[]) {QApplication a(argc, argv);QTranslator translator;const QStringList uiLanguages = QLocale::system().uiLanguages();for (const QString &locale : uiLanguages) {const QString baseName = "Snake_" + QLocale(locale).name();if (translator.load(":/i18n/" + baseName)) {a.installTranslator(&translator);break;}}Widget w;w.show();return a.exec(); }
相关文章:

基于C++的QT实现贪吃蛇小游戏
文章目录: 一:效果演示 二:实现思路 三:代码实现 widget.h widget.cpp main.cpp 一:效果演示 效果图◕‿◕✌✌✌ 代码下载 二:实现思路 通过按键控制蛇的移动,每吃一个商品蛇身就会加长…...

Spring Boot整合RabbitMQ之路由模式(Direct)
RabbitMQ中的路由模式(Direct模式)应该是在实际工作中运用的比较多的一种模式了,这个模式和发布与订阅模式的区别在于路由模式需要有一个routingKey,在配置上,交换机类型需要注入DirectExchange类型的交换机bean对象。…...

行式存储与列式存储
1.概述 数据处理大致可分为两大类,联机事务处理OLTP(on-line transaction processing) 和联机分析处理OLAP(on-line analytical processing)。 OLTP是传统关系型数据库的主要应用,用来执行一些基本的、日常的事务处理,比如数据库记录的增、删…...

windows上sqlserver的ldf日志文件和数据mdf文件分别放到不同的磁盘
之前我的windows上已安装好了sqlserver2017,有一个名为TestDb的数据库。ldf文件和mdf文件都一起放在D:\Database目录下。现在需要把ldf日志文件到E盘的database目录下。 重要的事情先说三遍 先停止网关(例如nginx)并备份数据库 先停止网关&am…...

vue3+uni——watch监听props中的数据(组件参数接收与传递defineProps、defineEmits)
案例说明 A页面引用的子组件B A页面 <template><view>//引用组件<serviceOrder change"change" :list"list" :current"type"></serviceOrder></view> </template><script setup>import serviceOrd…...

mybatis与spring集成与spring aop集成pagehelper插件
Mybatis与Spring的集成 Mybatis是一款轻量级的ORM框架,而Spring是一个全栈式的框架,二者的结合可以让我们更加高效地进行数据持久化操作。 Mybatis与Spring的集成主要有两种方式:使用Spring的Mybatis支持和使用Mybatis的Spring支持。 使用…...

Mybatis基础
...

TypeScript-- 配置Typescript环境(1)ts 转js,tsc --watch 实时编译
文章目录 安装Typescript判断是否有运行权限编写第一Typescript文件手动编译Ts文件转Js文件实时编译 安装Typescript npm install -g typescript 判断是否有运行权限 命令行运行 tsc -v 遇到了权限问题 用管理员打开window自带的powershell 运行如下指令即可: Set-…...

Dockerfile快速搭建自己专属的LAMP环境,生成镜像lamp:v1.1,并推送到私有仓库
环境: CentOS 7 Linux 3.10.0-1160.el7.x86_64 具体要求如下: (1)基于centos:6基础镜像; (2)指定作者信息; (3)安装httpd、mysql、mysql-server、php、ph…...

Lottery抽奖项目学习第二章第一节:环境、配置、规范
Lottery抽奖项目学习第二章第一节:环境、配置、规范 环境、配置、规范 下面以DDD架构和设计模式落地实战的方式,进行讲解和实现分布式抽奖系统的代码开发,那么这里会涉及到很多DDD的设计思路和设计模式应用,以及互联网大厂开发中…...
OpenCV之reshape函数
函数原型: /** brief Changes the shape and/or the number of channels of a 2D matrix without copying the data.The method makes a new matrix header for \*this elements. The new matrix may have a different sizeand/or different number of channels. A…...

【JavaEE】Spring事务-@Transactional参数介绍-事务的隔离级别以及传播机制
【JavaEE】Spring事务(2) 文章目录 【JavaEE】Spring事务(2)1. Transactional 参数介绍1.1 value 和 transactionManager1.2 timeout1.3 readOnly1.4 后面四个1.5 isolation 与 propagation 2. Spring 事务隔离级别 - isolation2.…...

微信小程序canvas type=2d生成海报保存到相册、文字换行溢出显示...、文字删除线、分享面板
一、简介 做个简单的生成二维码海报分享,我做的时候也找简单的方法看能不能实现页面直接截图那种生成图片,原生小程序不支持,不多介绍下面有全部代码有注释、参数自行替换运行看看,还有需要优化的地方,有问题可以咨询…...
C++卷积神经网络
C卷积神经网络 #include"TP_NNW.h" #include<iostream> #pragma warning(disable:4996) using namespace std; using namespace mnist;float* SGD(Weight* W1, Weight& W5, Weight& Wo, float** X) {Vector2 ve(28, 28);float* temp new float[10];V…...
go 读取yaml映射到struct
安装 go get gopkg.in/yaml.v3创建yaml Mysql:Host: 192.168.214.134Port: 3306UserName: wwPassword: wwDatabase: go_dbCharset: utf8mb4ParseTime: trueLoc: LocalListValue:- haha- test- vv JWTSecret: nidaye定义结构体 type Mysql struct {Host string yaml:&…...

Redis 10 大数据类型
1. which 10 1. redis字符串 2. redis 列表 3. redis哈希表 4. redis集合 5. redis有序集合 6. redis地理空间 7. redis基数统计 8. redis位图 9. redis位域 10. redis流 2. 获取redis常见操作指令 官网英文:https://redis.io/commands 官网中文:https:/…...

优化生产流程:数字化工厂中的OPC UA分布式IO模块应用
背景 近年来,为了提升在全球范围内的竞争力,制造企业希望自己工厂的机器之间协同性更强,自动化设备采集到的数据能够发挥更大的价值,越来越多的传统型工业制造企业开始加入数字化工厂建设的行列,实现智能制造。 数字化…...

Elasticsearch(十四)搜索---搜索匹配功能⑤--全文搜索
一、前言 不同于之前的term。terms等结构化查询,全文搜索首先对查询词进行分析,然后根据查询词的分词结果构建查询。这里所说的全文指的是文本类型数据(text类型),默认的数据形式是人类的自然语言,如对话内容、图书名…...

已解决Gradle错误:“Unable to load class ‘org.gradle.api.plugins.MavenPlugin‘”
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...

windows中安装sqlite
1. 下载文件 官网下载地址:https://www.sqlite.org/download.html 下载sqlite-dll-win64-x64-3430000.zip和sqlite-tools-win32-x86-3430000.zip文件(32位系统下载sqlite-dll-win32-x86-3430000.zip)。 2. 安装过程 解压文件 解压上一步…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...

解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...

华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...

使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...