文章详情

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

请输入下面的图形验证码

提交验证

短信预约提醒成功

QT实现贪吃蛇游戏代码详解

2024-04-02 19:55

关注

一、新建一个Qt项目

新建Qt Widgets Application,项目名称为HappySnake,基类选择QWidget,类名默认

二、添加要用到的头文件


#include <QKeyEvent>
#include <QRectF>
#include <QPainter>
#include <QPen>
#include <QBrush>
#include <QDebug>
#include <QTimer>
#include <QTime>

三、写类声明信息


class Widget : public QWidget
{
    Q_OBJECT
 
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
protected:
    void paintEvent(QPaintEvent *);
    void keyPressEvent(QKeyEvent *);
 
private:
    void addTopRectF();
    void addDownRectF();
    void addLeftRectF();
    void addRightRectF();
    void deleteLastRectF();
    bool snakeStrike();
    enum Move{Left,Right,Up,Down};
protected slots:
    void timeOut();
    void rewardTimeOut();
 
private:
    Ui::Widget *ui;
    QList<QRectF> snake;//贪吃蛇本体
    int snakeNodeWidth = 10;
    int snakeNodeHeight = 10;
    QTimer *timer;
    QTimer *rewardTimer;
    int time = 100;
    int moveFlage = Up;
    bool gameOver = false;
    bool gameStart = false;
    QList<QRectF> rewardNode;//奖励节点
 
};

四、对类函数的实现

构造函数


Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    resize(480,500);
    //设置窗体背景色为黑色
    setStyleSheet("QWidget{background:black}");
    setWindowOpacity(0.8);//设置窗口的透明度
 
    snake.append(QRectF(200,500,snakeNodeWidth,snakeNodeHeight));
    addTopRectF();
    addTopRectF();
    //首先生成一个奖励节点
    rewardNode.append(QRectF(100,100,snakeNodeWidth,snakeNodeWidth));
 
    timer = new QTimer;
    connect(timer, SIGNAL(timeout()),this,SLOT(timeOut()));
    //timer->start(time);
 
    rewardTimer = new QTimer;
    connect(rewardTimer,SIGNAL(timeout()),this,SLOT(rewardTimeOut()));
    //rewardTimer->start(time*30);
}
 
Widget::~Widget()
{
    delete ui;
}

界面刷新


void Widget::timeOut()
{
    int flage = 1;
    for(int i=0; i<rewardNode.length(); i++){
        if(rewardNode.at(i).contains(snake.at(0).topLeft()+QPointF(snakeNodeWidth/2,snakeNodeHeight/2))){
        //if(snake.at(0).contains(rewardNode.at(i).x()+rewardNode.at(i).width()/2,rewardNode.at(i).y()+rewardNode.at(i).height()/2)){
            if(rewardNode.at(i).width()>snakeNodeWidth){//额外奖励
                flage += 2;
            }
            flage++;//正常奖励
            rewardNode.removeAt(i);
            break;
        }
    }
    while(flage--){
        switch (moveFlage) {
        case Up:
            addTopRectF();
            break;
        case Down:
            addDownRectF();
            break;
        case Right:
            addRightRectF();
            break;
        case Left:
            addLeftRectF();
            break;
        default:
            break;
        }
    }
    deleteLastRectF();
 
    update();
}

随机奖励的生成


//随机奖励
void Widget::rewardTimeOut()
{
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
    if(rewardNode.length() > 5){
        rewardNode.removeAt(qrand()%5);
    }
    rewardNode.append(QRectF(qrand()%(this->width()/20)*20,qrand()%(this->height()/20)*20,snakeNodeWidth,snakeNodeWidth));
    if(qrand()%5 == 3){
        rewardNode.append(QRectF(qrand()%(this->width()/20)*20-5,qrand()%(this->height()/20)*20-5,snakeNodeWidth*2,snakeNodeWidth*2));
    }
}

移动


//向上移动
void Widget::addTopRectF()
{
    if(snake.at(0).y()-snakeNodeHeight < 0){
        snake.insert(0,QRectF(QPointF(snake.at(0).x(),this->height()-snakeNodeHeight),
                              QPointF(snake.at(0).x()+snakeNodeWidth,this->height())));
    }else{
        snake.insert(0,QRectF(snake.at(0).topLeft()+QPointF(0,-snakeNodeHeight),snake.at(0).topRight()));
    }
}
//向下移动
void Widget::addDownRectF()
{
    if(snake.at(0).y()+snakeNodeHeight*2 > this->height()){
        snake.insert(0,QRectF(QPointF(snake.at(0).x(),snakeNodeHeight),
                              QPointF(snake.at(0).x()+snakeNodeWidth,0)));
    }else{
        snake.insert(0,QRectF(snake.at(0).bottomLeft(),snake.at(0).bottomRight()+QPointF(0,snakeNodeHeight)));
    }
}
//向左移动
void Widget::addLeftRectF()
{
    if(snake.at(0).x()-snakeNodeWidth < 0){
        snake.insert(0,QRectF(QPointF(this->width()-snakeNodeWidth,snake.at(0).y()),
                              QPointF(this->width(),snake.at(0).y()+snakeNodeHeight)));
    }else{
        snake.insert(0,QRectF(snake.at(0).topLeft()+QPointF(-snakeNodeWidth,0),snake.at(0).bottomLeft()));
    }
}
//向右移动
void Widget::addRightRectF()
{
    if(snake.at(0).x()+snakeNodeWidth*2 > this->width()){
        snake.insert(0,QRectF(QPointF(0,snake.at(0).y()),
                              QPointF(snakeNodeWidth,snake.at(0).y()+snakeNodeHeight)));
    }else{
        snake.insert(0,QRectF(snake.at(0).topRight(),snake.at(0).bottomRight()+QPointF(snakeNodeWidth,0)));
    }
}
//删除结尾数据
void Widget::deleteLastRectF()
{
    snake.removeLast();
}

绘图


//绘图
void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QPen pen;
    QBrush brush;
    QFont font("方正舒体",12,QFont::ExtraLight,false);
 
    //反锯齿
    painter.setRenderHint(QPainter::Antialiasing);
 
    pen.setColor(Qt::black);
    brush.setColor(Qt::green);
    brush.setStyle(Qt::SolidPattern);
    painter.setPen(pen);
    painter.setBrush(brush);
 
    for(int i=0; i<snake.length(); i++){
        painter.drawRect(snake.at(i));
    }
    brush.setColor(Qt::red);
    painter.setBrush(brush);
    for(int i=0; i<rewardNode.length(); i++){
        painter.drawEllipse(rewardNode.at(i));
    }
    pen.setColor(Qt::white);
    painter.setPen(pen);
    painter.setFont(font);
    painter.drawText(20,20,QString("当前得分:")+QString("%1").arg(snake.length()));
 
    if(snakeStrike()){
        QFont font("方正舒体",30,QFont::ExtraLight,false);
        painter.setFont(font);
        painter.drawText((this->width()-300)/2,(this->height()-30)/2,QString("GAME OVER!"));
        timer->stop();
        rewardTimer->stop();
        gameOver = true;
    }
 
    QWidget::paintEvent(event);
}

按键事件


void Widget::keyPressEvent(QKeyEvent *event)
{
    switch(event->key()){
    case Qt::Key_Up:
        if(moveFlage != Down){
            moveFlage = Up;
        }
        break;
    case Qt::Key_Down:
        if(moveFlage != Up){
            moveFlage = Down;
        }
        break;
    case Qt::Key_Right:
        if(moveFlage != Left){
            moveFlage = Right;
        }
        break;
    case Qt::Key_Left:
        if(moveFlage != Right){
            moveFlage = Left;
        }
        break;
    case Qt::Key_Enter:
    case Qt::Key_Return:
        if(gameOver){
            snake.clear();
            rewardNode.clear();
            moveFlage = Up;
            snake.append(QRectF(200,500,snakeNodeWidth,snakeNodeHeight));
            addTopRectF();
            addTopRectF();
            //首先生成一个奖励节点
            rewardNode.append(QRectF(100,100,snakeNodeWidth,snakeNodeWidth));
            timer->start(time);
            rewardTimer->start(time*30);
            gameOver = false;
        }
        break;
    case Qt::Key_Space:
        if(gameStart && !gameOver){
            timer->start(time);
            rewardTimer->start(time*30);
            gameStart = false;
        }else if(!gameStart && !gameOver){
            timer->stop();
            rewardTimer->stop();
            gameStart = true;
        }
        break;
    default:
        break;
    }
}

判断蛇身是否相撞


//判断蛇头是否和蛇身相撞
bool Widget::snakeStrike()
{
    for(int i=0; i<snake.length(); i++){
        for(int j=i+1; j<snake.length(); j++){
            if(snake.at(i) == snake.at(j)){
                return true;
            }
        }
    }
    return false;
 
}

五、结束

实现的效果:


总结:

只是简单的使用了paintevent进行绘图,基本都是简单的对Qt的一些常用类的使用,对面向对象的编程应用的不是很好,更偏向于面向过程,所以完全可以改成C语言在Linux下实现,思路都是相同的。

到此这篇关于QT实现贪吃蛇游戏代码详解的文章就介绍到这了,更多相关QT内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

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

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

软考中级精品资料免费领

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

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

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

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

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

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

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