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…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...




