QT实现贪吃蛇 --好家伙,直接上代码

好家伙,我直接好家伙,拿走直接运行~

看下效果,再下拉看代码实现 ! ! !
在这里插入图片描述

老规矩,直接上代码<双击空格开始,单击空格控制暂停与开始>

.h写的啥

#ifndef WIDGET_H
#define WIDGET_H

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

namespace Ui {
    
    
class Widget;
}

class Widget : public QWidget  // 继承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(); // 删除last数据
    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;
};

#endif // WIDGET_H

.cpp写的啥

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    
    
    ui->setupUi(this);
    resize(600,500);
    setStyleSheet("QWidget{background:gray}");
    snake.append(QRectF(200,500,snakeNodeWidth,snakeNodeHeight));
    addTopRectF();
    addTopRectF();
    // 在坐标(400,200)处设置第一个瓜
    rewardNode.append(QRectF(400,200,snakeNodeWidth,snakeNodeWidth));

    timer = new QTimer;
    connect(timer, SIGNAL(timeout()),this,SLOT(timeOut()));

    rewardTimer = new QTimer;
    connect(rewardTimer,SIGNAL(timeout()),this,SLOT(rewardTimeOut()));
    this->setWindowTitle("All In 贪吃蛇Demo");
}

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(rewardNode.at(i).width()>snakeNodeWidth){
    
    
                flage += 2; // 吃个大瓜+2
            }
            flage++; // 吃个小瓜+1
            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 fontg ( "Microsoft YaHei", 20, 50);

    painter.setRenderHint(QPainter::Antialiasing);

    pen.setColor(Qt::black);
    brush.setColor(Qt::lightGray);
    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::green);
    painter.setBrush(brush);
    for(int i=0; i<rewardNode.length(); i++){
    
    
        painter.drawEllipse(rewardNode.at(i));
    }
    pen.setColor(Qt::black);
    painter.setPen(pen);
    painter.setFont(fontg);
    painter.drawText(245,40,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;
}

猜你喜欢

转载自blog.csdn.net/hwx802746/article/details/109534051