文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

QT如何实现贪吃蛇游戏

2023-06-15 02:34

关注

这篇文章主要介绍了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_OBJECTpublic:    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_OBJECTprivate:    //蛇坐标结构    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_OBJECTpublic :    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如何实现贪吃蛇游戏”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网行业资讯频道,更多相关知识等着你来学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯