当前位置: 首页 > news >正文

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);
}

需要项目的源文件,私发。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • redis全局唯一ID生成策略、countDownLatch、Lambda表达式总结
  • 《峡谷小狐仙-多模态角色扮演游戏助手》复现流程
  • Java IO模型深入解析:BIO、NIO与AIO
  • 为什么 FPGA 的效率低于 ASIC?
  • SpringBoot之拦截器(Interceptor)
  • Rust代码答疑报错|Python一对一辅导答疑
  • sql查询报错空指针怎么解决?
  • Anything LLM ,构建自己的 RAG 架构 LLM,学习自己的知识库
  • HCIP之PPP协议(PAP认证,CHAP认证)、GRE、MGRE综合实验
  • git -.gitignore不生效的问题
  • React 18【实用教程】(2024最新版)
  • 从dev分支合并到master分支
  • Vue 3项目安装Element-Plus
  • el-table表格 及其el-pagination分页 封装及其使用
  • 【深度学习】sdxl的Lora训练技巧
  • 《剑指offer》分解让复杂问题更简单
  • 【译】理解JavaScript:new 关键字
  • 2017 年终总结 —— 在路上
  • 2018一半小结一波
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • CSS相对定位
  • Django 博客开发教程 8 - 博客文章详情页
  • Git同步原始仓库到Fork仓库中
  • JavaScript对象详解
  • leetcode46 Permutation 排列组合
  • magento 货币换算
  • Redis中的lru算法实现
  • SpingCloudBus整合RabbitMQ
  • Spring声明式事务管理之一:五大属性分析
  • 对象引论
  • 高度不固定时垂直居中
  • 关于字符编码你应该知道的事情
  • 那些年我们用过的显示性能指标
  • 浅谈JavaScript的面向对象和它的封装、继承、多态
  • 微信小程序开发问题汇总
  • 一些关于Rust在2019年的思考
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • ​马来语翻译中文去哪比较好?
  • ​香农与信息论三大定律
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • #### go map 底层结构 ####
  • #{} 和 ${}区别
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (五)activiti-modeler 编辑器初步优化
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (一)Neo4j下载安装以及初次使用
  • (转)scrum常见工具列表
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • .cn根服务器被攻击之后
  • .java 9 找不到符号_java找不到符号