温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

QT如何实现贪吃蛇游戏

发布时间:2021-05-18 10:29:23 来源:亿速云 阅读:441 作者:小新 栏目:开发技术

这篇文章主要介绍了QT如何实现贪吃蛇游戏,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

为了熟悉QT的相关知识,我用了大约8个小时的时间用QT再次写了一遍贪吃蛇。

因为QT的机制和平时写的程序流程不同,所以程序中可能没有遵守代码规范。

运行效果:

QT如何实现贪吃蛇游戏

程序内除了实现贪吃蛇的基本功能外,还添加了记录得分、调节游戏速度、重新开始游戏等功能。

游戏内容使用QPainter类进行绘制。

编译环境:

Windows Qt 5.9.0 Qt Creator 4.3.0

思路:

数组存储蛇节点坐标的贪吃蛇游戏思路。

因为编写过程中使用了分文件编写,且QT框架的其他部分较多,这里仅展示程序实现主要代码。

代码:

MainWindow.h 主窗口类头文件

#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QPainter>     //画家类 #include "snake.h"      //蛇类 #include <QKeyEvent>    //键盘事件 #include "food.h"       //食物类 #include <QTimer>       //定时器类 namespace Ui { class Widget; } class Widget : public QWidget {     Q_OBJECT public:     explicit Widget(QWidget *parent = 0);     ~Widget();     //绘图事件     void paintEvent(QPaintEvent *);     //游戏结束的情况     void GameOver(); private:     Ui::Widget *ui;     Snake snake;        //蛇对象     char key = 'd';     //接收键值,初始向右     Food food;          //食物对象     //创建定时器     QTimer *timer = new QTimer(this);     bool gameflag = false;//游戏结束标记     int score = 0;      //记录得分     int timerspeed = 200; //定时器速度     bool bugflag = false; //用于解决操控过快导致撞死自己的bug的标志     //键盘事件,改变键值     void keyPressEvent(QKeyEvent *ev); }; #endif // WIDGET_H

MainWindow.cpp函数实现

#include "MainWindow.h" #include "ui_widget.h" #include <QLabel> #include <QPushButton> //主窗口构造函数 Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) {     ui->setupUi(this);      //初始化出.ui界面     //一个格子宽高25像素,地图宽高600像素,每行有24个格子     //设置固定窗口大小     setFixedSize(1000,600);     //设置得分标签控件的属性     ui->label->setFont(QFont("黑体", 20, QFont::Bold, false));     //设置游戏速度标签内容     ui->label_2->setFont(QFont("楷体", 16, QFont::Bold, false));     ui->label_2->setText("游戏速度:");     //滑动条控件,这里将数值按一定比例放大缩小     ui->horizontalSlider->setValue(200 >> 2);     //监听滑动条控件滑动时,改变定时器速度为滑动条的值     connect(ui->horizontalSlider,QSlider::valueChanged,[=]()     {         timerspeed = ui->horizontalSlider->value() << 2;     });     //设置重新开始按钮属性和内容     ui->pushButton_3->setFont(QFont("黑体",12));     ui->pushButton_3->setText("重新开始");     //监听重新开始按钮     connect(ui->pushButton_3,QPushButton::clicked,[=]()     {         snake.Reset();      //重置蛇         score = 0;          //得分清0         key = 'd';          //key值向右         timerspeed = 200 << 2;//重置游戏速度         timer->start(timerspeed);//重置定时器         ui->horizontalSlider->setValue(200 >> 2);//重置滑动条         gameflag = false;   //重置游戏结束标志     });     //开启定时器     timer->start(timerspeed);     //监听定时器的信号,执行表达式内容     connect(timer,&QTimer::timeout,[=]()     {         timer->start(timerspeed); //调整定时器的速度         snake.Move(key);    //蛇移动函数         //吃到食物的情况         (food.getfoodX() == snake.snakevec.at(0).x && food.getfoodY() == snake.snakevec.at(0).y) ?         score++, food.randfood():    //得分+1,随机产生一个食物坐标         snake.snakevec.pop_back();   //删除蛇尾         GameOver();    //游戏失败的情况         update();      //调用绘图函数         //更新标签控件的文本内容         ui->label->setText(QString("得分:%1").arg(score));     }); } //游戏失败情况 void Widget::GameOver() {     //撞墙失败     if(snake.snakevec.at(0).x >= 24 * 25 || snake.snakevec.at(0).x < 0 ||        snake.snakevec.at(0).y < 0 || snake.snakevec.at(0).y >= 24 * 25)     {         gameflag = true;         timer->stop();      //暂停定时器         return;     }     //撞自己失败     for(int i = 1; i < snake.snakevec.size(); i++)     {         if(snake.snakevec.at(0).x == snake.snakevec.at(i).x &&            snake.snakevec.at(0).y == snake.snakevec.at(i).y)             gameflag = true, timer->stop();     } } //绘图事件 void Widget::paintEvent(QPaintEvent *) {     //创建画家对象,指定绘图设备为this主窗口     QPainter painter(this);     //设置画刷为红色     QBrush brush2(Qt::red);     //让画家使用画刷     painter.setBrush(brush2);     //画食物     painter.drawRect(QRect(food.getfoodX(),food.getfoodY(),25,25));     //设置画刷为黑色     QBrush brush3(Qt::blue);     painter.setBrush(brush3);     //遍历蛇坐标容器,画出代表蛇身的矩形     for(auto snakenodei : snake.snakevec)         //蛇头画圆形         (snakenodei.x == snake.snakevec.at(0).x &&          snakenodei.y == snake.snakevec.at(0).y) ?         //蛇头画圆形         painter.setRenderHint(QPainter::Antialiasing),  //用抗锯齿画圆         painter.drawEllipse(QPoint(snakenodei.x + 12,snakenodei.y + 12),12,12):         //蛇身画矩形         painter.drawRect(QRect(snakenodei.x,snakenodei.y,25,25));     bugflag = false;    //在画出蛇之后将标志设为假     //设置画刷为黑色     QBrush brush4(QColor(128, 64, 0));     painter.setBrush(brush4);     //画出墙壁     for(int i = 0; i < 24; i++)           painter.drawRect(QRect(25 * 25, i * 25, 25, 25));     //游戏结束时的绘图     if(gameflag)     {   //设置文字属性         QFont font("楷体", 80, QFont::Bold, false);         painter.setFont(font);      //使用字体         painter.drawText(QRect(240, 200, 1000, 500), "游戏结束");   //画出游戏结束文字     } } //键盘事件,改变贪吃蛇移动方向 void Widget::keyPressEvent(QKeyEvent *ev) {     if(bugflag)     //bug标志为真直接返回         return;     switch (ev->key())     {     case Qt::Key_W:         if(key == 's') break;   //按下与当前方向相反按键时break         key = 'w';         bugflag = true; break;        //按键之后将标志设为真     case Qt::Key_S:         if(key == 'w') break;         key = 's';         bugflag = true; break;     case Qt::Key_A:         if(key == 'd') break;         key = 'a';         bugflag = true; break;     case Qt::Key_D:         if(key == 'a') break;         key = 'd';         bugflag = true; break;     case Qt::Key_Space:     //空格键暂停,这里有点问题         timer->stop(); break;     default:                //其他键重启定时器         timer->start(timerspeed);     } } //析构 Widget::~Widget() {     delete ui; }

snake.h 蛇类头文件

#ifndef SNAKE_H #define SNAKE_H #include <QWidget> #include <QVector>      //Qt动态数组类 class Snake : public QWidget {     Q_OBJECT private:     //蛇坐标结构     struct  Snakecoor     {         int x;         int y;     }; public:     explicit Snake(QWidget *parent = nullptr);     //蛇坐标容器     QVector<Snakecoor> snakevec;     //蛇移动主要函数     void Move(char key);     //根据key值确定蛇的移动方向     void DeteDirMove(char key, Snakecoor &nexthead);     //重置蛇     void Reset(); signals: public slots: }; #endif // SNAKE_H

snake.cpp 蛇类函数实现

#include "snake.h" //构造函数初始化一条蛇 Snake::Snake(QWidget *parent) : QWidget(parent) {     Snakecoor snakenode;            //临时结构变量用于创建蛇     for (int i = 5; i >= 0; i--) //从右向左创建5节蛇身,容器的第一个元素为蛇头     {         snakenode.x = 25 * 8 + i * 25;//每个格子宽25像素         snakenode.y = 25 * 8;         snakevec.push_back(snakenode);//将蛇节点插入到数组中     } } //确定蛇的移动方向,确定新蛇头的坐标位置 inline void Snake::DeteDirMove(char key, Snakecoor &nexthead) {     switch (key)     {     case 'w':         //新蛇头坐标根据旧蛇头坐标改变         nexthead.x = snakevec.front().x;         nexthead.y = snakevec.front().y - 25;         break;     case 's':         nexthead.x = snakevec.front().x;         nexthead.y = snakevec.front().y + 25;         break;     case 'a':         nexthead.x = snakevec.front().x - 25;         nexthead.y = snakevec.front().y;         break;     case 'd':         nexthead.x = snakevec.front().x + 25;         nexthead.y = snakevec.front().y;     } } //蛇移动主要函数 void Snake::Move(char key) {     Snakecoor nexthead;  //创建一个新的蛇头     DeteDirMove(key, nexthead);  //确定新蛇头的位置     snakevec.insert(snakevec.begin(), nexthead);    //将新蛇头插入到容器头部 } //重置蛇函数 void Snake::Reset() {     snakevec.clear();   //清空容器     //初始化蛇     Snakecoor snakenode;     for (int i = 5; i >= 0; i--)     {         snakenode.x = 25 * 8 + i * 25;         snakenode.y = 25 * 8;         snakevec.push_back(snakenode);     } }

food.h 食物类头文件

#ifndef FOOD_H #define FOOD_H #include <QWidget> class Food : public QWidget {     Q_OBJECT public :     int food_x = 0;     //食物坐标     int food_y = 0; public:     explicit Food(QWidget *parent = nullptr);     void randfood();    //随机产生食物坐标     int getfoodX();     //返回食物坐标     int getfoodY(); signals: public slots: }; #endif // FOOD_H

food.cpp 食物类函数实现

#include "food.h" #include <ctime> Food::Food(QWidget *parent) : QWidget(parent) {     randfood();     //创建对象时产生就一个随机坐标 } //随机产生食物坐标 void Food::randfood() {     srand((unsigned)time(NULL));     food_x = (rand() % 24) * 25;     food_y = (rand() % 24 )* 25; } //获取食物的坐标 int Food::getfoodX() {     return food_x; } int Food::getfoodY() {     return food_y; }

感谢你能够认真阅读完这篇文章,希望小编分享的“QT如何实现贪吃蛇游戏”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

qt
AI