Qt:26.Qt项目:贪吃蛇游戏
一、项目功能演示:
- 开始界面可以点击进入游戏。
- 点击进入游戏之后,切换到选项界面,该界面可以选择游戏难度,回退,以及查询最近一次游戏得分。
- 游戏具体界面如下。贴图啥的可以自己换,本人审美不咋行,随便找的贴图。
二、文件展示:
三、项目代码:
1.打开窗口实现:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QPushButton> #include <QLabel> #include <QFont> #include <QSound> #include "gameselect.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {//初始化窗口,标题,图标,窗口大小ui->setupUi(this);this->setWindowTitle("贪吃蛇");this->setWindowIcon(QIcon(":/image/pix.png"));this->setFixedSize(600,400);//窗口背景设置,将图片设置自动拉伸QLabel* label=new QLabel(this);label->setGeometry(0,0,this->width(),this->height());label->setPixmap(QPixmap(":/image/enter.jpg"));label->setScaledContents(true);//设置进入按钮QPushButton* enter_but=new QPushButton(this);enter_but->move(250,250);enter_but->setText("进入游戏");enter_but->setStyleSheet("QPushButton{border:0px;color:red;}");//按钮文本设置QFont font("华文行楷",18);enter_but->setFont(font);//创建选项页面,设置点击音效,打开新窗口,关闭旧窗口GameSelect* gameSelect=new GameSelect;connect(enter_but,&QPushButton::clicked,[=](){gameSelect->setGeometry(this->geometry());QSound::play(":/image/6.wav");gameSelect->show();this->close();});}MainWindow::~MainWindow() {delete ui; }
2.选项窗口实现:
#include "gameselect.h" #include <QIcon> #include <QLabel> #include <QDebug> #include <QVBoxLayout> #include <QPushButton> #include <QFont> #include "mainwindow.h" #include <QSound> #include "gameroom.h" #include <QFile>GameSelect::GameSelect(QWidget *parent) : QWidget(parent) {//窗口大小固定,设置图标,标题this->setFixedSize(600,400);this->setWindowTitle("关卡选择");this->setWindowIcon(QIcon(":/image/pix.png"));//加载背景QLabel* label=new QLabel(this);label->setGeometry(this->geometry());label->setPixmap(QPixmap(":/image/load.jpg"));//创建一个widget对象存放布局管理器,管理选项按钮QWidget* widget=new QWidget(this);widget->setGeometry(150,100,300,250);//创建布局管理器,并将它设置到widget对象QVBoxLayout* layout=new QVBoxLayout;widget->setLayout(layout);//选项按钮创建QPushButton* but_easy=new QPushButton("简单模式");QPushButton* but_normal=new QPushButton("正常模式");QPushButton* but_diff=new QPushButton("困难模式");QPushButton* but_grades=new QPushButton("战绩查询");QPushButton* but_ret=new QPushButton("返回上页");//按钮添加到布局管理器layout->addWidget(but_easy);layout->addWidget(but_normal);layout->addWidget(but_diff);layout->addWidget(but_grades);layout->addWidget(but_ret);//设置按钮的拉伸策略,是的可以占满整个布局管理器but_easy->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);but_normal->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);but_diff->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);but_grades->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);but_ret->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);QFont font("华文行楷",25);widget->setFont(font);//设置按钮无边框,文本显示颜色为蓝色but_easy->setStyleSheet("QPushButton{border: 0px;color:blue;}");but_normal->setStyleSheet("QPushButton{border: 0px;color:blue;}");but_diff->setStyleSheet("QPushButton{border: 0px;color:blue;}");but_grades->setStyleSheet("QPushButton{border: 0px;color:blue;}");but_ret->setStyleSheet("QPushButton{border: 0px;color:blue;}");//连接按钮和槽函数,直接使用lambda表达式connect(but_ret,&QPushButton::clicked,[=](){MainWindow* mainwindow=new MainWindow;QSound::play(":/image/6.wav");mainwindow->show();this->close();});GameRoom* room=new GameRoom;connect(but_easy,&QPushButton::clicked,[=](){room->setGeometry(this->geometry());QSound::play(":/image/6.wav");room->show();this->close();room->setMoveTimeout(300);});connect(but_normal,&QPushButton::clicked,[=](){room->setGeometry(this->geometry());QSound::play(":/image/6.wav");room->show();this->close();room->setMoveTimeout(200);});connect(but_diff,&QPushButton::clicked,[=](){room->setGeometry(this->geometry());QSound::play(":/image/6.wav");room->show();this->close();room->setMoveTimeout(100);});connect(but_grades, &QPushButton::clicked, [=]() {QSound::play(":/image/6.wav");QWidget* widget = new QWidget;widget->setWindowTitle("历史分数");widget->setWindowIcon(QIcon(":/image/pix.png"));widget->setFixedSize(400, 200);QLabel* label=new QLabel(widget);label->setGeometry(0,0,400,200);QFile file("C:/Users/86133/Desktop/Qt-tmp.txt");file.open(QIODevice::ReadOnly);QTextStream in(&file);QString grade=in.readLine();QFont font("行书",30);label->setFont(font);label->setText("最近得分:"+ grade);widget->show();});}
3.游戏窗口实现
#include "gameroom.h" #include <QIcon> #include <QPainter> #include <QTimer> #include <QPushButton> #include <QMessageBox> #include "gameselect.h" #include <QFile> #include <QTextStream> #include <QShortcut>GameRoom::GameRoom(QWidget *parent) : QWidget(parent) {//初始化窗口,标题,图标,大小this->setWindowTitle("游戏房间");this->setWindowIcon(QIcon(":/image/pix.png"));this->setFixedSize(600,400);//尾插一个节点作为头节点snakeList.push_back(QRectF(160,220,kSnakeNodeWidth,kSnakeNodeHeight));moveUp();moveUp();//创建食物createFood();//定时器设置timer=new QTimer(this);connect(timer,&QTimer::timeout,[=](){//如果吃到食物,重新生成食物int cnt=1;if(snakeList.front().intersects(foodRect)){createFood();cnt++;}//通过食物数量,控制移动的距离while(cnt--){switch (moveDirect){case SnakeDirect::UP:moveUp();break;case SnakeDirect::DOWN:moveDown();break;case SnakeDirect::LEFT:moveLeft();break;case SnakeDirect::RIGHT:moveRight();break;}}snakeList.pop_back();update();});//开始和暂停按钮QPushButton* sta_but=new QPushButton("开始游戏",this);QPushButton* stop_but=new QPushButton("暂停游戏",this);sta_but->move(450,100);stop_but->move(450,150);QFont font("楷体",15);sta_but->setFont(font);stop_but->setFont(font);//开始功能实现,音乐播放,音乐持续播放设置connect(sta_but,&QPushButton::clicked,[=](){isGameStart=true;timer->start(moveTimeout);sound=new QSound(":/image/2.wav");sound->play();sound->setLoops(-1);});connect(stop_but,&QPushButton::clicked,[=](){isGameStart=false;timer->stop();sound->stop();});//移动按钮设置QPushButton* up=new QPushButton("↑",this);QPushButton* down=new QPushButton("↓",this);QPushButton* left=new QPushButton("←",this);QPushButton* right=new QPushButton("→",this);up->move(480,230);down->move(480,270);left->move(440,250);right->move(520,250);up->setStyleSheet("QPushButton{border:0px}");down->setStyleSheet("QPushButton{border:0px}");left->setStyleSheet("QPushButton{border:0px}");right->setStyleSheet("QPushButton{border:0px}");QFont ft("楷体",25);up->setFont(ft);down->setFont(ft);left->setFont(ft);right->setFont(ft);QShortcut* s1=new QShortcut(QKeySequence("W"),up);QShortcut* s2=new QShortcut(QKeySequence("S"),down);QShortcut* s3=new QShortcut(QKeySequence("A"),left);QShortcut* s4=new QShortcut(QKeySequence("D"),right);QObject::connect(s1,&QShortcut::activated,up,&QPushButton::click);QObject::connect(s2,&QShortcut::activated,down,&QPushButton::click);QObject::connect(s3,&QShortcut::activated,left,&QPushButton::click);QObject::connect(s4,&QShortcut::activated,right,&QPushButton::click);connect(up,&QPushButton::clicked,[=](){if(moveDirect!=SnakeDirect::DOWN)moveDirect=SnakeDirect::UP;});connect(down,&QPushButton::clicked,[=](){if(moveDirect!=SnakeDirect::UP)moveDirect=SnakeDirect::DOWN;});connect(left,&QPushButton::clicked,[=](){if(moveDirect!=SnakeDirect::RIGHT)moveDirect=SnakeDirect::LEFT;});connect(right,&QPushButton::clicked,[=](){if(moveDirect!=SnakeDirect::LEFT)moveDirect=SnakeDirect::RIGHT;});//退出按钮QPushButton* exit_but=new QPushButton("退出游戏",this);exit_but->move(450,350);exit_but->setFont(font);QMessageBox* msg=new QMessageBox(this);QPushButton* ok=new QPushButton("ok");QPushButton* cancel=new QPushButton("cancel");msg->addButton(ok,QMessageBox::AcceptRole);msg->addButton(cancel,QMessageBox::RejectRole);msg->setWindowTitle("退出");msg->setText("是否确定退出?");connect(exit_but,&QPushButton::clicked,[=](){msg->exec();QSound::play(":/image/6.wav");if(msg->clickedButton()==ok){GameSelect* gameselect=new GameSelect;gameselect->show();this->close();}else{msg->close();}});}void GameRoom::paintEvent(QPaintEvent *event) {QPainter painter(this);QPixmap pix;pix.load(":/image/main.jpg");painter.drawPixmap(0,0,400,400,pix);pix.load(":/image/control.jpg");painter.drawPixmap(400,0,200,400,pix);//绘制蛇头if(moveDirect==SnakeDirect::UP)pix.load(":/image/up.png");else if(moveDirect==SnakeDirect::DOWN)pix.load(":/image/down.png");else if(moveDirect==SnakeDirect::LEFT)pix.load(":/image/left.png");elsepix.load(":/image/right.png");auto snakeHead=snakeList.front();painter.drawPixmap(snakeHead.x(),snakeHead.y(),snakeHead.width(),snakeHead.height(),pix);//绘制蛇身pix.load(":/image/circle.png");for(int i=1;i<snakeList.size()-1;i++){auto node=snakeList.at(i);painter.drawPixmap(node.x(),node.y(),node.width(),node.height(),pix);}//绘制蛇尾auto snakeTail=snakeList.back();painter.drawPixmap(snakeTail.x(),snakeTail.y(),snakeTail.width(),snakeTail.height(),pix);//绘制食物pix.load(":/image/Hamburg.png");painter.drawPixmap(foodRect.x(),foodRect.y(),kSnakeNodeWidth,kSnakeNodeHeight,pix);//将分数绘制到界面QPen pen;pen.setColor(Qt::black);painter.setPen(pen);QFont font("楷体",15);painter.setFont(font);painter.drawText(430,30,"当前等分:");painter.drawText(530,30,QString("%1").arg(snakeList.size()-3));//绘制失败效果if(checkFail()){pen.setColor(Qt::red);QFont font("楷体",30);painter.setPen(pen);painter.setFont(font);painter.drawText(100,180,"Game Over");timer->stop();sound->stop();}//将当前分数保存到文件中int c=snakeList.size()-3;QFile file("C:/Users/86133/Desktop/Qt-tmp.txt");if(file.open(QIODevice::WriteOnly | QIODevice::Text)){QTextStream out(&file);int num=c;out<<num;file.close();}}void GameRoom::moveUp() {QPointF leftTop;QPointF rightBottom;auto snakeHead=snakeList.front();int headX=snakeHead.x();int headY=snakeHead.y();if(headY<20){leftTop=QPointF(headX,this->height()-kSnakeNodeHeight);}else{leftTop=QPointF(headX,headY-kSnakeNodeHeight);}rightBottom=leftTop+QPointF(kSnakeNodeWidth,kSnakeNodeHeight);snakeList.push_front(QRectF(leftTop,rightBottom)); }void GameRoom::moveDown() {QPointF leftTop;QPointF rightBottom;auto snakeHead=snakeList.front();int headX=snakeHead.x();int headY=snakeHead.y();if(headY>this->height()-40){leftTop=QPointF(headX,0);}else{leftTop=snakeHead.bottomLeft();}rightBottom=leftTop+QPointF(kSnakeNodeWidth,kSnakeNodeHeight);snakeList.push_front(QRectF(leftTop,rightBottom)); }void GameRoom::moveLeft() {QPointF leftTop;QPointF rightBottom;auto snakeHead=snakeList.front();int headX=snakeHead.x();int headY=snakeHead.y();if(headX<20){leftTop=QPointF(400-kSnakeNodeWidth,headY);}else{leftTop=QPointF(headX-kSnakeNodeWidth,headY);}rightBottom=leftTop+QPointF(kSnakeNodeWidth,kSnakeNodeHeight);snakeList.push_front(QRectF(leftTop,rightBottom)); }void GameRoom::moveRight() {QPointF leftTop;QPointF rightBottom;auto snakeHead=snakeList.front();int headX=snakeHead.x();int headY=snakeHead.y();if(headX>360){leftTop=QPointF(0,headY);}else{leftTop=snakeHead.topRight();}rightBottom=leftTop+QPointF(kSnakeNodeWidth,kSnakeNodeHeight);snakeList.push_front(QRectF(leftTop,rightBottom)); }bool GameRoom::checkFail() {for(int i=0;i<snakeList.size();i++){for(int j=i+1;j<snakeList.size();j++){if(snakeList.at(i)==snakeList.at(j)){return true;}}}return false; }void GameRoom::createFood() {foodRect=QRectF(qrand()%(400/kSnakeNodeWidth)*kSnakeNodeWidth,qrand()%(400/kSnakeNodeHeight)*kSnakeNodeHeight,kSnakeNodeWidth,kSnakeNodeHeight); }
需要项目的源文件,私发。
相关文章:

Qt:26.Qt项目:贪吃蛇游戏
一、项目功能演示: 开始界面可以点击进入游戏。 点击进入游戏之后,切换到选项界面,该界面可以选择游戏难度,回退,以及查询最近一次游戏得分。 游戏具体界面如下。贴图啥的可以自己换,本人审美不咋行&#x…...

通过HTML/CSS 实现各类进度条的功能。
需求:我们在开发中会遇到使用各式各样的进度条,因为当前插件里面进度条各式各样的,为了方便我们定制化的开发和方便修改样式,我们这里使用HTML和CSS样式来进行开发进度条功能。 通过本文学习我们会明白如何使用 HTML/CSS 创建各种…...

Opencv学习项目3——人脸识别
之前我们获取了一张图像的人脸信息,现在我们来使用特征点分析来匹配两张lyf照片的相似度 获取两张图片的人脸信息 import cv2 import face_recognition# 加载图像文件 img1 face_recognition.load_image_file(lyf1.png) img2 face_recognition.load_image_file(l…...
【js自学打卡11】生成器函数(generator函数)的使用总结+代码举例
力扣的js入门免费题刷完了,开始自己找题练练,顺便捡捡知识点 力扣2649 1.思路 一眼递归,但事实证明也可以直接flat手撕。 arr.flat(Infinity) //直接扁平化到最底层涉及到了一些关于生成器和异步编程相关的知识点,学一下。 2.…...

深入了解jdbc-02-CRUD
文章目录 操作和访问数据库Statement操作数据表的弊端sql注入问题PreparedStatement类ResultSet类与ResultSetMetaData类资源的释放批量插入 操作和访问数据库 数据库的调用的不同方式: Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。PreparedStatem…...

《基于 Kafka + Quartz 实现时限质控方案》
📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…...
浏览器的卡顿与react的解决思路
以下内容是阅读过程中结合自己的思考而诞生的产物,不一定准确,但相反的,可能个人对实际情况有很大的误解。 仅做参考,欢迎指正。 前面提到浏览器显示的其实是渲染流程最后渲染出来的一张图片,而一个行为引起的副作用需…...

XXE:XML外部实体引入
XXE漏洞 如果服务器没有对客户端的xml数据进行限制,且版本较低的情况下,就可能会产生xxe漏洞 漏洞利用流程 1.客户端发送xml文件,其中dtd存在恶意的外部实体引用 2.服务器进行解析 3.服务器返回实体引用内容 危害:任意文件读…...

3D培训大师创新培训体验,加速空调关键组件的高效精准安装
如今,空调系统的复杂性和精密性与日俱增,对专业技术人员的要求也日益提高。尤其是决定空调是否能平稳运行的空调关键组件的装配培训,不再局限于传统的理论讲解和实体模型演示,而是更注重数字化、沉浸式学习。 案例背景 某空调公…...

PyTorch 深度学习实践-循环神经网络(高级篇)
视频指路 参考博客笔记 参考笔记二 文章目录 上课笔记总代码练习 上课笔记 个人能力有限,重看几遍吧,第一遍基本看不懂 名字的每个字母都是一个特征x1,x2,x3…,一个名字是一个序列 rnn用GRU 用ASCII表作为词典,长度为128&#x…...

这才是老板喜欢的电子信息类简历
点击可直接使用...
MySQL学习之事务,锁机制
事务 什么是事务? 事务就是逻辑上的一组操作,要么全做,要么全不做 事务经典例子:转账,转账需要两个操作,从一个人账户上减钱,在另一个账户上加钱,比如说小红给小明转账100元&…...

开源知识付费小程序源码 内容付费系统php源码 含完整图文部署教程
在当今数字化时代,知识付费作为一种新型的经济模式,正逐渐受到越来越多内容创作者、专家及商家的青睐。开源知识付费小程序源码和内容付费系统PHP源码作为实现这一模式的重要工具,为构建高效、安全、可扩展的知识付费平台提供了强大的技术支持…...

时序数据库如何选型?详细指标总结!
工业物联网场景,如何判断什么才是好的时序数据库? 工业物联网将机器设备、控制系统与信息系统、业务过程连接起来,利用海量数据进行分析决策,是智能制造的基础设施,并影响整个工业价值链。工业物联网机器设备感知形成了…...
【前端】JavaScript入门及实战51-55
文章目录 51 函数52 函数的参数53 返回值54 练习55 return 51 函数 <!DOCTYPE html> <html> <head> <title></title> <meta charset "utf-8"> <script type"text/javascript">/* 函数:1. 函数也是…...

【引领未来智造新纪元:量化机器人的革命性应用】
在日新月异的科技浪潮中,量化机器人正以其超凡的智慧与精准的操作,悄然改变着各行各业的生产面貌,成为推动产业升级、提升竞争力的关键力量。今天,让我们一同探索量化机器人在不同领域的广泛应用价值,见证它如何以科技…...
山东航空小程序查询
山东航空小程序 1) 请求地址 https://scxcx.sda.cn/mohe/proxy?url/trp/ticket/search 2) 调用方式:HTTP post 3) 接口描述: 接口描述详情 4) 请求参数: {"dep": "TAO","arr": "HRB","flightDate&qu…...

MySQL添加索引时会锁表吗?
目录 简介Online DDL概念Online DDL用法总结 简介 在MySQL5.5以及之前的版本,通常更改数据表结构操作(DDL)会阻塞对表数据的增删改操作(DML)。 MySQL5.6提供Online DDL之后可支持DDL与DML操作同时执行,降低…...

算法日记day 16(二叉树的广度优先遍历|反转、对称二叉树)
一、二叉树的层序遍历 题目: 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:[[3]…...

PolarisMesh源码系列--Polaris-Go注册发现流程
导语 北极星是腾讯开源的一款服务治理平台,用来解决分布式和微服务架构中的服务管理、流量管理、配置管理、故障容错和可观测性问题。在分布式和微服务架构的治理领域,目前国内比较流行的还包括 Spring Cloud,Apache Dubbo 等。在 Kubernete…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...

DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...