ToB企服应用市场:ToB评测及商务社交产业平台

标题: 【Qt】探索Qt框架:开发经典贪吃蛇游戏的全过程与实践 [打印本页]

作者: 怀念夏天    时间: 2024-7-20 06:56
标题: 【Qt】探索Qt框架:开发经典贪吃蛇游戏的全过程与实践
引言

贪吃蛇游戏是一款历史悠久且广受欢迎的经典电子游戏,最早可以追溯到1976年的"Snake Game"。它在1997年作为诺基亚手机的内置游戏而变得家喻户晓,其简朴的操作和上瘾的游戏性迅速赢得了全球玩家的喜爱。贪吃蛇的流行度不但体现在其在手机平台上的普及,还扩展到了个人电脑、游戏机等其他平台,成为跨期间的电子游戏代表作。
使用Qt框架开发贪吃蛇游戏具有多方面的上风。Qt是一个功能强盛且跨平台的应用程序开发框架,它提供了丰富的GUI控件和工具,使得用户界面的设计变得直观和高效。Qt的事件驱动架构和网络功能为实现响应式控制和多人在线游戏提供了强盛支持。此外,Qt的开源特性和活跃的社区支持,为开发者提供了大量的资源和文档,低沉了开发难度和成本。Qt的性能优化和集成开发环境也极大提升了开发效率,使得使用Qt开发贪吃蛇游戏成为一个抱负的选择。
项目链接:

源代码:gitee:https://gitee.com/q-haodong/test_-qt/tree/master/Qt/greedy_snake
效果演示视频:https://live.csdn.net/v/409583?spm=1001.2014.3001.5501

     Qt贪吃蛇游戏
  
1. Qt框架的使用简介

在Qt贪吃蛇代码中,Qt的基本组件和模块紧张包罗:

2. 贪吃蛇游戏设计

2.1 游戏规则和玩法介绍

贪吃蛇是一款经典的电子游戏,其基本规则和玩法如下:

2.2 游戏界面设计概述

贪吃蛇游戏的界面设计通常包罗以下几个部分:
这些界面元素通过Qt的各种组件实现,例如使用QPushButton来创建按钮,使用QPainter和QPixmap来绘制游戏区域的图形,以及使用QTimer来控制游戏的革新率和蛇的移动速度。此外,界面的布局和样式通过Qt的布局管理器和样式表来设计,确保界面的美观和用户友好性。
3. 核心代码分析

3.1 主界面(GameHall)

3.1.1 布局和功能介绍

GameHall 类代表贪吃蛇游戏的主界面,它为玩家提供了进入游戏的出发点。以下是主界面的紧张布局和功能:

3.1.2 代码实现分析

在代码层面,GameHall 类的实现涉及以下几个关键部分:
  1. GameHall::GameHall(QWidget *parent)
  2.     : QWidget(parent)
  3.     , ui(new Ui::GameHall)
  4. {
  5.     ui->setupUi(this);
  6.     this->setFixedSize(1000, 800); //设置窗口大小
  7.     this->setWindowIcon(QIcon(":res/ico.jpg")); // 设置窗口图标
  8.     this->setWindowTitle("贪吃蛇游戏");
  9.     QPushButton* strBtn = new QPushButton(this);
  10.     strBtn->move(410, 500);
  11.     strBtn->setText("开始游戏");
  12.     strBtn->setToolTip("这是游戏开始按钮,鼠标点击或者回车键进入!");
  13.     strBtn->setToolTipDuration(3000);
  14.     ButtonStyle::setCommonStyle_green(strBtn, 30);
  15.     // 为按钮设置回车快捷键
  16.     strBtn->setShortcut(Qt::Key_Return);
  17.     GameSelect* gameSelect = new GameSelect;
  18.     connect(strBtn, &QPushButton::clicked, [=](){
  19.         QSound::play(":res/clicked.wav");
  20.         this->close();
  21.         gameSelect->setGeometry(this->geometry()); // 第二个窗口和第一个窗口一样大
  22.         gameSelect->show();
  23.     });
复制代码
}
  1. void GameHall::paintEvent(QPaintEvent *event)
  2. {
  3.      Q_UNUSED(event); // 告诉编译器event参数是未使用的
  4.     // 实例化画家
  5.     QPainter painter(this);
  6.     // 实例化绘图设备
  7.     QPixmap pix(":res/game_hall.jpg");
  8.     // 绘画
  9.     painter.drawPixmap(0,0, this->width(), this->height(), pix);
  10. }
复制代码
  1. GameHall::~GameHall()
  2. {
  3.     delete ui;
  4. }
复制代码
3.2 游戏选择界面(GameSelect)

3.2.1 功能介绍

GameSelect 类构成了贪吃蛇游戏的选择界面,答应玩家根据本身的喜好选择差别的游戏难度。这个界面通常包罗以下几个关键功能:

3.2.2 代码实现分析

在代码层面,GameSelect 类的实现涉及以下关键部分:
  1. GameSelect::GameSelect(QWidget *parent) : QWidget(parent)
  2. {
  3.     this->setFixedSize(1000, 800); // 设置窗口大小
  4.     this->setWindowIcon(QIcon(":res/ico.jpg"));
  5.     this->setWindowTitle("游戏选择界面");
  6.     // 创建并设置返回键的位置
  7.     QPushButton* backBtn = new QPushButton(this);
  8.     backBtn->move(80, 50);
  9.     backBtn->setIcon(QIcon(":res/back.png"));
  10.     backBtn->setToolTip("点击此按钮或按键盘Esc键返回游戏大厅界面");
  11.     backBtn->setShortcut(Qt::Key_Escape);
  12.     backBtn->setIconSize(QSize(50, 50)); // 设置图标大小
  13.     // 设置样式表
  14.     ButtonStyle::setCommonStyle_write(backBtn, 26);
  15.     connect(backBtn, &QPushButton::clicked, [=](){
  16.         this->close();
  17.         QSound::play(":res/clicked.wav");
  18.         GameHall* gameHall = new GameHall;
  19.         gameHall->show();
  20.     });
  21.     GameRoom* gameRoom = new GameRoom;
  22.     QPushButton* simpleBtn = new QPushButton(this);
  23.     simpleBtn->move(420, 300);
  24.     simpleBtn->setText("简单模式");
  25.     simpleBtn->setToolTip("点击此按钮或按数字键1进入简单模式");
  26.     simpleBtn->setShortcut(Qt::Key_1);
  27.     ButtonStyle::setCommonStyle_green(simpleBtn, 26);
  28.     connect(simpleBtn, &QPushButton::clicked, [=](){
  29.         QSound::play(":res/clicked.wav");
  30.         this->close();
  31.         gameRoom->setGeometry(this->geometry());
  32.         gameRoom->show();
  33.         gameRoom->setTimeout(300);
  34.     });
  35.     QPushButton* normalBtn = new QPushButton(this);
  36.     normalBtn->move(420, 380);
  37.     normalBtn->setText("常规模式");
  38.     normalBtn->setToolTip("点击此按钮或按数字键2进入常规模式");
  39.     normalBtn->setShortcut(Qt::Key_2);
  40.     ButtonStyle::setCommonStyle_green(normalBtn, 26);
  41.     connect(normalBtn, &QPushButton::clicked, [=](){
  42.         QSound::play(":res/clicked.wav");
  43.         this->close();
  44.         gameRoom->setGeometry(this->geometry());
  45.         gameRoom->show();
  46.         gameRoom->setTimeout(200);
  47.     });
  48.     QPushButton* hardBtn = new QPushButton(this);
  49.     hardBtn->move(420, 460);
  50.     hardBtn->setText("困难模式");
  51.     hardBtn->setToolTip("点击此按钮或按数字键3进入困难模式");
  52.     hardBtn->setShortcut(Qt::Key_3);
  53.     ButtonStyle::setCommonStyle_green(hardBtn, 26);
  54.     connect(hardBtn, &QPushButton::clicked, [=](){
  55.         QSound::play(":res/clicked.wav");
  56.         this->close();
  57.         gameRoom->setGeometry(this->geometry());
  58.         gameRoom->show();
  59.         gameRoom->setTimeout(100);
  60.     });
  61.     QPushButton* hisBtn = new QPushButton(this);
  62.     hisBtn->move(420, 560);
  63.     hisBtn->setText("历史战绩");
  64.     hisBtn->setToolTip("点击此按钮或按键盘H查看历史记录");
  65.     hisBtn->setShortcut(Qt::Key_H);
  66.     ButtonStyle::setCommonStyle_write(hisBtn, 26);
  67.     connect(hisBtn, &QPushButton::clicked, [=](){
  68.         QWidget* widget = new QWidget;
  69.         widget->setWindowTitle("历史战绩");
  70.         widget->setFixedSize(500, 300);
  71.         QTextEdit* edit = new QTextEdit(widget);
  72.         QFont font("微软雅黑", 24);
  73.         edit->setFont(font);
  74.         edit->setFixedSize(500, 300);
  75.         QFile file("D:/Acode/class111/test_-qt/Qt/greedy_snake/snake/history.txt");
  76.         file.open(QIODevice::ReadOnly);
  77.         QTextStream in(&file);
  78.         int data = in.readLine().toInt();
  79.         edit->append("得分为: ");
  80.         edit->append(QString::number(data));
  81.         widget->show();
  82.     });
  83. }
复制代码
  1. void GameSelect::paintEvent(QPaintEvent *event)
  2. {
  3.     Q_UNUSED(event);
  4.     QPainter painter(this); // 实例化画图对象
  5.     QPixmap pix(":res/game_select.jpg");
  6.     painter.drawPixmap(0, 0, this->width(), this->height(), pix);
  7. }
复制代码
3.3 游戏房间(GameRoom)

3.3.1 游戏逻辑和核默算法分析

GameRoom 类是实现贪吃蛇游戏逻辑的核心,包罗蛇的移动、食品生成和游戏失败条件的检测。
3.3.2 代码实现细节

  1. GameRoom::GameRoom(QWidget *parent) : QWidget(parent)
  2. {
  3.     this->setFixedSize(1000, 800); //设置窗口大小
  4.     this->setWindowIcon(QIcon(":res/ico.jpg")); // 设置窗口图标
  5.     this->setWindowTitle("贪吃蛇游戏");
  6.     // 初始化贪吃蛇
  7.     snakeList.push_back(QRectF(this->width() / 2, this->height() / 2, kSnakeNodeWidth, kSnakeNodeHeight));
  8.     moveUp();
  9.     moveUp();
  10.     // 创建食物
  11.     createNewFood();
  12.     timer = new QTimer(this);
  13.     connect(timer, &QTimer::timeout, [=](){
  14.         int cnt = 1; // 默认移动一个
  15.         if (snakeList.front().intersects(foodRect)) // 判断蛇头是否与蛇相交
  16.         {
  17.             createNewFood();
  18.             cnt++; // 有食物相交的话移动2个
  19.         }
  20.         while(cnt--)
  21.         {
  22.             switch (moveDirect) {
  23.             case SnakeDirect::UP:
  24.                 moveUp();
  25.                 break;
  26.             case SnakeDirect::DOWN:
  27.                 moveDown();
  28.                 break;
  29.             case SnakeDirect::LEFT:
  30.                 moveLeft();
  31.                 break;
  32.             case SnakeDirect::RIGHT:
  33.                 moveRight();
  34.                 break;
  35.             default:
  36.                 break;
  37.             }
  38.         }
  39.         snakeList.pop_back(); // 删除最后一个节点
  40.         update();
  41.     });
  42.     // 开始游戏 暂停游戏
  43.     QPushButton* strBtn = new QPushButton(this);
  44.     strBtn->move(840, 120);
  45.     strBtn->setText("开始/暂停");
  46.     strBtn->setToolTip("点击此按钮或按键盘P键,切换游戏开始和暂停");
  47.     strBtn->setShortcut(Qt::Key_P);
  48.     ButtonStyle::setCommonStyle_green(strBtn, 20);
  49.     connect(strBtn, &QPushButton::clicked, [=](){
  50.         if (isGameStart == false)
  51.         {
  52.             isGameStart = true;
  53.             timer->start(moveTimeout);
  54.             sound = new QSound(":res/Trepak.wav");
  55.             sound->play();
  56.             sound->setLoops(-1);
  57.         }
  58.         else
  59.         {
  60.             isGameStart = false;
  61.             timer->stop();
  62.             sound->stop();
  63.         }
  64.     });
  65.     QPushButton* backBtn = new QPushButton(this);
  66.     backBtn->move(855, 200);
  67.     backBtn->setIcon(QIcon(":res/back.png"));
  68.     backBtn->setToolTip("点击此按钮或按键盘Esc键返回游戏大厅界面");
  69.     backBtn->setShortcut(Qt::Key_Escape);
  70.     backBtn->setIconSize(QSize(50, 50)); // 设置图标大小
  71.     // 设置样式表
  72.     ButtonStyle::setCommonStyle_write(backBtn, 26);
  73.     connect(backBtn, &QPushButton::clicked, [=](){
  74.         this->close();
  75.         QSound::play(":res/clicked.wav");
  76.         GameSelect* gameselect = new GameSelect;
  77.         gameselect->show();
  78.         if (isGameStart == true) {
  79.             isGameStart = false;
  80.             timer->stop();
  81.             sound->stop();
  82.         }
  83.     });
  84.     // 方向控制
  85.     QPushButton* up = new QPushButton(this);
  86.     QPushButton* down = new QPushButton(this);
  87.     QPushButton* left = new QPushButton(this);
  88.     QPushButton* right = new QPushButton(this);
  89.     // 为每个按钮创建快捷键
  90.     QShortcut* upShortcut = new QShortcut(QKeySequence(Qt::Key_Up), this);
  91.     QShortcut* downShortcut = new QShortcut(QKeySequence(Qt::Key_Down), this);
  92.     QShortcut* leftShortcut = new QShortcut(QKeySequence(Qt::Key_Left), this);
  93.     QShortcut* rightShortcut = new QShortcut(QKeySequence(Qt::Key_Right), this);
  94.     // 连接快捷键的activated信号到按钮的clicked信号
  95.     connect(upShortcut, SIGNAL(activated()), up, SLOT(animateClick()));
  96.     connect(downShortcut, SIGNAL(activated()), down, SLOT(animateClick()));
  97.     connect(leftShortcut, SIGNAL(activated()), left, SLOT(animateClick()));
  98.     connect(rightShortcut, SIGNAL(activated()), right, SLOT(animateClick()));
  99.     up->move(875, 405);
  100.     down->move(875,455);
  101.     left->move(810,455);
  102.     right->move(930,455);
  103.     up->setText("↑");
  104.     ButtonStyle::setCommonStyle_green(up,20);
  105.     down->setText("↓");
  106.     ButtonStyle::setCommonStyle_green(down,20);
  107.     left->setText("←");
  108.     ButtonStyle::setCommonStyle_green(left,20);
  109.     right->setText("→");
  110.     ButtonStyle::setCommonStyle_green(right,20);
  111.     connect(up, &QPushButton::clicked, [=](){
  112.         if (moveDirect != SnakeDirect::DOWN)
  113.         {
  114.             moveDirect = SnakeDirect::UP;
  115.         }
  116.     });
  117.     connect(down, &QPushButton::clicked,[=](){
  118.         if (moveDirect != SnakeDirect::UP)
  119.         {
  120.             moveDirect = SnakeDirect::DOWN;
  121.         }
  122.     });
  123.     connect(left, &QPushButton::clicked, [=](){
  124.         if (moveDirect != SnakeDirect::RIGHT)
  125.         {
  126.             moveDirect = SnakeDirect::LEFT;
  127.         }
  128.     });
  129.     connect(right, &QPushButton::clicked, [=](){
  130.         if (moveDirect != SnakeDirect::LEFT)
  131.         {
  132.             moveDirect = SnakeDirect::RIGHT;
  133.         }
  134.     });
  135.     // 退出游戏
  136.     QPushButton* ExitBtn = new QPushButton(this);
  137.     ExitBtn->move(860, 700);
  138.     ExitBtn->setText("退出");
  139.     ButtonStyle::setCommonStyle_green(ExitBtn, 20);
  140.     QMessageBox* messageBox = new QMessageBox(this);
  141.     QPushButton* ok = new QPushButton("ok");
  142.     QPushButton* cancel = new QPushButton("cancel");
  143.     messageBox->addButton(ok, QMessageBox::AcceptRole);
  144.     messageBox->addButton(cancel, QMessageBox::RejectRole);
  145.     messageBox->setWindowTitle("警告");
  146.     messageBox->setText("是否确认退出!");
  147.     messageBox->setIcon(QMessageBox::Warning);
  148.     connect(ExitBtn, &QPushButton::clicked, [=](){
  149.         messageBox->show();
  150.         messageBox->exec(); // 事件轮询
  151.         QSound::play(":res/clicked.wav");
  152.         if(messageBox->clickedButton() == ok)
  153.         {
  154.             this->close();
  155.         }
  156.         else
  157.         {
  158.             messageBox->close();
  159.         }
  160.     });
  161. }
复制代码
  1. void GameRoom::moveUp()
  2. {
  3.     QPointF leftTop; // 左上角坐标
  4.     QPointF rightBottom; // 右下角坐标
  5.     auto snakeNode = snakeList.front(); //头
  6.     int headX = snakeNode.x();
  7.     int headY = snakeNode.y();
  8.     if (headY < 0) // 穿墙了
  9.     {
  10.         leftTop = QPointF(headX, this->height() - kSnakeNodeHeight);
  11.     }
  12.     else
  13.     {
  14.         leftTop = QPointF(headX, headY - kSnakeNodeHeight);
  15.     }
  16.     rightBottom = leftTop + QPointF(kSnakeNodeWidth, kSnakeNodeHeight);
  17.     snakeList.push_front(QRectF(leftTop, rightBottom));
  18. }
复制代码
  1. void GameRoom::createNewFood()
  2. {
  3.     foodRect = QRectF(qrand() % (800/ kSnakeNodeWidth) * kSnakeNodeWidth,
  4.                       qrand() % (this->height() / kSnakeNodeHeight) * kSnakeNodeHeight,
  5.                       kSnakeNodeWidth,
  6.                       kSnakeNodeHeight);
  7. }
复制代码
  1. // 创建食物
  2. createNewFood();
  3. timer = new QTimer(this);
  4. connect(timer, &QTimer::timeout, [=](){
  5.     int cnt = 1; // 默认移动一个
  6.     if (snakeList.front().intersects(foodRect)) // 判断蛇头是否与蛇相交
  7.     {
  8.         createNewFood();
  9.         cnt++; // 有食物相交的话移动2个
  10.     }
  11.     while(cnt--)
  12.     {
  13.         switch (moveDirect) {
  14.         case SnakeDirect::UP:
  15.             moveUp();
  16.             break;
  17.         case SnakeDirect::DOWN:
  18.             moveDown();
  19.             break;
  20.         case SnakeDirect::LEFT:
  21.             moveLeft();
  22.             break;
  23.         case SnakeDirect::RIGHT:
  24.             moveRight();
  25.             break;
  26.         default:
  27.             break;
  28.         }
  29.     }
  30.     snakeList.pop_back(); // 删除最后一个节点
  31.     update();
  32. });
复制代码
  1. bool GameRoom::checkFail()
  2. {
  3.     // 遍历蛇的身体节点,检查是否有重叠
  4.     for (int i = 0; i < snakeList.size(); ++i)
  5.     {
  6.         for (int j = i + 1; j < snakeList.size(); ++j)
  7.         {
  8.             if (snakeList.at(i) == snakeList.at(j))
  9.             {
  10.                 // 发现重叠,游戏失败
  11.                 return true;
  12.             }
  13.         }
  14.     }
  15.     // 没有发现重叠,游戏继续
  16.     return false;
  17. }
复制代码
  1. void GameRoom::paintEvent(QPaintEvent *event)
  2. {
  3.     Q_UNUSED(event);
  4.     QPainter painter(this); // 实例化画家对象
  5.     QPixmap pix;
  6.     pix.load(":res/game_room.jpg");
  7.     painter.drawPixmap(0, 0, 800, 800, pix);
  8.     pix.load(":res/bg1.jpeg");
  9.     painter.drawPixmap(800, 0, 200, 800, pix);
  10.     // 绘制蛇:蛇头 + 蛇身体 + 蛇尾巴
  11.     // 绘制蛇头:上 下 左 右
  12.     if(moveDirect == SnakeDirect::UP)
  13.     {
  14.         pix.load(":res/up.png");
  15.     }
  16.     else if (moveDirect == SnakeDirect::DOWN)
  17.     {
  18.         pix.load(":res/down.png");
  19.     }
  20.     else if (moveDirect == SnakeDirect::LEFT)
  21.     {
  22.         pix.load(":res/left.png");
  23.     }
  24.     else if (moveDirect == SnakeDirect::RIGHT)
  25.     {
  26.         pix.load(":res/right.png");
  27.     }
  28.     auto snakeHead = snakeList.front();
  29.     painter.drawPixmap(snakeHead.x(), snakeHead.y(), snakeHead.width(), snakeHead.height(), pix);
  30.     // 绘制蛇身
  31.     pix.load(":res/Bd.png");
  32.     for (int i = 1; i < snakeList.size()-1; ++i)
  33.     {
  34.         auto node = snakeList.at(i);
  35.         painter.drawPixmap(node.x(), node.y(), node.width(), node.height(), pix);
  36.     }
  37.     // 绘制蛇尾巴
  38.     auto snakeTail = snakeList.back();
  39.     painter.drawPixmap(snakeTail.x(), snakeTail.y(), snakeTail.width(), snakeTail.height(), pix);
  40.     // 绘制食物
  41.     pix.load(":res/food.png");
  42.     painter.drawPixmap(foodRect.x(), foodRect.y(), foodRect.width(), foodRect.height(), pix);
  43.     // 绘制分数
  44.     pix.load(":res/sorce_bg.png");
  45.     painter.drawPixmap(this->width()*0.85, this->height()*0.06, 90, 40, pix);
  46.     QPen pen;
  47.     pen.setColor(Qt::black);
  48.     painter.setPen(pen);
  49.     QFont font("微软雅黑");
  50.     font.setPixelSize(24); // 设置字体大小为20像素
  51.     painter.setFont(font);
  52.     painter.drawText(this->width()*0.9, this->height()*0.1, QString("%1").arg(snakeList.size()));
  53.     // 往文件中写分数
  54.     int c = snakeList.size();
  55.     QFile file("D:/Acode/class111/test_-qt/Qt/greedy_snake/snake/history.txt");
  56.     if (file.open(QIODevice::WriteOnly | QIODevice::Text))
  57.     {
  58.         QTextStream out(&file);
  59.         out << c;
  60.         qDebug() << c;
  61.         file.close();
  62.     } else {
  63.          qDebug() << "文件打开失败";
  64.     }
  65.     // 绘制游戏失败效果
  66.     if (checkFail())
  67.     {
  68.         pen.setColor(Qt::red);
  69.         painter.setPen(pen);
  70.         QFont font("微软雅黑", 50);
  71.         painter.drawText(this->width()*0.45, this->height()*0.5, QString("GAME OVER!"));
  72.         timer->stop();
  73.         QSound::play(":res/gameover.wav");
  74.     }
  75. }
复制代码
  1.     // 往文件中写分数
  2.     int c = snakeList.size();
  3.     QFile file("D:/Acode/class111/test_-qt/Qt/greedy_snake/snake/history.txt");
  4.     if (file.open(QIODevice::WriteOnly | QIODevice::Text))
  5.     {
  6.         QTextStream out(&file);
  7.         out << c;
  8.         qDebug() << c;
  9.         file.close();
  10.     } else {
  11.          qDebug() << "文件打开失败";
  12.     }
  13.     // 绘制游戏失败效果
  14.     if (checkFail())
  15.     {
  16.         pen.setColor(Qt::red);
  17.         painter.setPen(pen);
  18.         QFont font("微软雅黑", 50);
  19.         painter.drawText(this->width()*0.45, this->height()*0.5, QString("GAME OVER!"));
  20.         timer->stop();
  21.         QSound::play(":res/gameover.wav");
  22.     }
  23. }
复制代码
3.4 按钮样式(ButtonStyle)

3.4.1 代码实现

  1. class ButtonStyle {
  2. public:
  3.     static void setCommonStyle_green(QPushButton *button, size_t font_size);
  4.     static void setCommonStyle_write(QPushButton *button, size_t font_size);
  5. };
复制代码
  1. void ButtonStyle::setCommonStyle_green(QPushButton *button, size_t font_size) {
  2.     QString styleSheet = R"(
  3.         QPushButton {
  4.             background-color: #4CAF50;
  5.             border: 2px solid #4CAF50;
  6.             border-radius: 10px;
  7.             font: bold %1px '微软雅黑';
  8.             color: white;
  9.             padding: 8px;
  10.             padding-left: 20px;
  11.             padding-right: 20px;
  12.         }
  13.         QPushButton:hover {
  14.             background-color: #45a049;
  15.         }
  16.         QPushButton:pressed {
  17.             background-color: #3e8e41;
  18.         }
  19.     )";
  20.     button->setStyleSheet(styleSheet.arg(font_size));
  21. }
  22. void ButtonStyle::setCommonStyle_write(QPushButton *button, size_t font_size) {
  23.     QString styleSheet = R"(
  24.         QPushButton {
  25.             font: bold %1px '微软雅黑';
  26.             border: 2px solid #a3a3a3;
  27.             border-radius: 16px;
  28.             background-color: rgba(255, 255, 255, 0);
  29.             padding: 8px;
  30.             padding-left: 20px;
  31.             padding-right: 20px;
  32.         }
  33.         QPushButton:hover {
  34.             background-color: rgba(180, 180, 180, 0.3);
  35.         }
  36.         QPushButton:pressed {
  37.             background-color: rgba(180, 180, 180, 0.4);
  38.         }
  39.     )";
  40.     button->setStyleSheet(styleSheet.arg(font_size));
  41. }
复制代码
3.4.2 实现效果

4. 图形和音效

4.1 图形资源

在贪吃蛇游戏中,图形资源紧张包罗:
4.2 音效资源

音效资源加强了游戏的互动性和沉醉感,包罗:
4.3 在Qt中加载和使用资源

在Qt中,图形和音效资源可以通过以下方式加载和使用:
示例代码:

  1. // 加载和使用图像资源
  2. QPixmap backgroundPixmap(":res/game_background.jpg");
  3. QPainter painter(this);
  4. painter.drawPixmap(0, 0, width(), height(), backgroundPixmap);
  5. // 加载和播放音效资源
  6. QSound clickSound(":res/click.wav");
  7. clickSound.play();
  8. // 使用QMediaPlayer播放背景音乐
  9. QMediaPlayer *musicPlayer = new QMediaPlayer;
  10. musicPlayer->setMedia(QUrl("qrc:/res/game_music.mp3"));
  11. musicPlayer->play();
复制代码
5. 调试和优化

5.1 调试技巧

5.2 性能优化建议

5.3 代码重构和改进方法

6. 扩展功能和未来方向

6.1 扩展功能

6.2 未来方向

6.3 技能实现


7. 总结

使用Qt开发贪吃蛇游戏是一个实践和展示Qt强盛功能的过程,同时也是深入了解C++在现代应用开发中应用代价的时机。以下是通过本项目获得的一些关键经验和认识:

总之,使用Qt开发贪吃蛇游戏不但是一种技能上的实践,也是对Qt和C++在游戏开发中应用潜力的探索。通过这个项目,开发者可以学习到宝贵的技能,并为未来的软件开发工作打下坚固的基础。
末端

随着本文的竣事,我盼望读者不但对使用Qt开发贪吃蛇游戏有了深入的了解,而且也被激励去实验本身的项目。开发应用程序,尤其是游戏,是一段充满挑战和学习时机的路程。鼓励动手实践,探索Qt文档,到场社区,开发个性化项目,并分享您的经验。同时,也要持续学习,接受反馈,并迭代改进。软件开发是一个不断进步的过程,享受编程和创造的过程,享受您在开发中取得的每一个进步和乐成。记住,每一个巨大的开发者都是从编写第一个“Hello World”程序开始的。所以,不要害怕犯错,不要害怕重新开始。每个项目都是成长和学习的时机。现在,开始您的Qt开发之旅,创造令人高兴的新作品,并与世界分享您的创造力吧!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4