欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

QT實現(xiàn)貪吃蛇游戲代碼詳解

 更新時間:2021年11月18日 09:29:15   作者:五里之南  
本文主要為大家詳細介紹了在QT中實現(xiàn)貪吃蛇游戲的詳細教程,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一、新建一個Qt項目

新建Qt Widgets Application,項目名稱為HappySnake,基類選擇QWidget,類名默認

二、添加要用到的頭文件

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

三、寫類聲明信息

  • 貪吃蛇的本體使用小方框來代替
  • 使用QList類來保存貪吃蛇的本體
  • 使用定時器來設(shè)定刷新的時間
  • 使用隨機函數(shù)生成獎勵的節(jié)點
  • 使用paintEvent來進行繪圖
  • keyPressEvent來監(jiān)測按鍵的按下,控制貪吃蛇的移動
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;//獎勵節(jié)點
 
};

四、對類函數(shù)的實現(xiàn)

構(gòu)造函數(shù)

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    resize(480,500);
    //設(shè)置窗體背景色為黑色
    setStyleSheet("QWidget{background:black}");
    setWindowOpacity(0.8);//設(shè)置窗口的透明度
 
    snake.append(QRectF(200,500,snakeNodeWidth,snakeNodeHeight));
    addTopRectF();
    addTopRectF();
    //首先生成一個獎勵節(jié)點
    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)));
    }
}
//刪除結(jié)尾數(shù)據(jù)
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();
            //首先生成一個獎勵節(jié)點
            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;
 
}

五、結(jié)束

實現(xiàn)的效果:


總結(jié):

只是簡單的使用了paintevent進行繪圖,基本都是簡單的對Qt的一些常用類的使用,對面向?qū)ο蟮木幊虘?yīng)用的不是很好,更偏向于面向過程,所以完全可以改成C語言在Linux下實現(xiàn),思路都是相同的。

到此這篇關(guān)于QT實現(xiàn)貪吃蛇游戲代碼詳解的文章就介紹到這了,更多相關(guān)QT內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • VC外部符號錯誤_main,_WinMain@16,__beginthreadex解決方法

    VC外部符號錯誤_main,_WinMain@16,__beginthreadex解決方法

    這篇文章主要介紹了VC外部符號錯誤_main,_WinMain@16,__beginthreadex解決方法,實例分析了比較典型的錯誤及對應(yīng)的解決方法,需要的朋友可以參考下
    2015-05-05
  • C++調(diào)用libcurl開源庫實現(xiàn)郵件的發(fā)送功能流程詳解

    C++調(diào)用libcurl開源庫實現(xiàn)郵件的發(fā)送功能流程詳解

    libcurl是一個免費開源的網(wǎng)絡(luò)傳輸庫,支持ftp、ftps、tftp,http、https、telnet、ldap、pop3、smtp等多種協(xié)議,接下來讓我們一起來了解吧
    2021-11-11
  • C++ 內(nèi)聯(lián)函數(shù)inline案例詳解

    C++ 內(nèi)聯(lián)函數(shù)inline案例詳解

    這篇文章主要介紹了C++ 內(nèi)聯(lián)函數(shù)inline案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • C語言實現(xiàn)輸入一個字符串后打印出該字符串中字符的所有排列

    C語言實現(xiàn)輸入一個字符串后打印出該字符串中字符的所有排列

    這篇文章主要介紹了C語言實現(xiàn)輸入一個字符串后打印出該字符串中字符的所有排列的方法,是數(shù)學(xué)中非常實用的排列算法,需要的朋友可以參考下
    2014-09-09
  • c語言詳解動態(tài)內(nèi)存分配及常見錯誤的解決

    c語言詳解動態(tài)內(nèi)存分配及常見錯誤的解決

    給數(shù)組分配多大的內(nèi)存空間?你是否和初學(xué)C時的我一樣,有過這樣的疑問。這一期就來聊一聊動態(tài)內(nèi)存的分配,讀完這篇文章,你可能對內(nèi)存的分配有一個更好的理解
    2022-04-04
  • 帶你了解如何用C++合并兩個有序鏈表

    帶你了解如何用C++合并兩個有序鏈表

    這篇文章主要介紹了c++ 如何合并兩個有序鏈表,小編感覺這篇文章還不錯,希望能幫助大家更好的理解和學(xué)習(xí)C++,感興趣的朋友可以了解下
    2021-08-08
  • OpenCV 2.4.3 C++ 平滑處理分析

    OpenCV 2.4.3 C++ 平滑處理分析

    平滑也稱模糊, 是一項簡單且使用頻率很高的圖像處理方法,本文將詳細介紹OpenCV 2.4+ C++ 平滑處理,需要了解更多的朋友可以詳細參考下
    2012-11-11
  • 淺談C++ Socket編程

    淺談C++ Socket編程

    本文給大家簡單介紹了C++中的Socket編程的種類以及sockets編程的8個步奏,簡單生動,有需要的小伙伴可以參考下
    2017-07-07
  • 詳解C語言實現(xiàn)猜數(shù)字游戲

    詳解C語言實現(xiàn)猜數(shù)字游戲

    這篇文章主要為大家介紹了C語言實現(xiàn)猜數(shù)字游戲,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助<BR>
    2022-01-01
  • C/C++ 宏詳細解析

    C/C++ 宏詳細解析

    關(guān)于宏的一些語法問題,可以在google上找到。相信我,你對于宏的了解絕對沒你想象的那么多。如果你還不知道#和##,也不知道prescan,那么你肯定對宏的了解不夠
    2013-09-09

最新評論