QT贪吃蛇-为什么蛇动不起来?

利用qt实现贪吃蛇小游戏,不明白为什么动不起来,以及怎么加背景图片。

感觉自己好像把这个程序写复杂了,看别的程序员的帖子好像寥寥几行就实现了


这是.h文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QKeyEvent>
#include <QTimer>
#include <QList>
#include <QRectF>

#include <QList>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

//1.按键
//2.定时器
//3.画图
enum Direct{
    DIR_LEFT,
    DIR_RIGHT,
    DIR_UP,
    DIR_DOWN
};

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

protected:
    void addTop();
    void addDown();
    void addRight();
    void addLeft();

    void addNewReward();
    //按键
    void keyPressEvent(QKeyEvent *event);
    void timeout();
    void paintEvent(QPaintEvent *event);
    void deleteLast();
    bool checkContact();
private:
    Ui::Widget *ui;
    int  moveflag = DIR_UP;
    bool blsRun;
    bool blsOver;

    //定时器
    QTimer *timer;
    int time = 100;
    //snake
    QList <QRectF> snake;
    //reward
    QRectF rewardNode;

    int nodeWidth = 20;
    int nodeHeight = 20;
};

#endif // WIDGET_H


这是.cpp文件

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

#include <QPainter>
#include <QRectF>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
    ,blsRun(false)
{
    ui->setupUi(this);

    //定时器
    timer = new QTimer();
    connect(timer,SIGNAL(timeout()),this,SLOT(timeout()));

    resize(600,368);
    setWindowTitle("贪吃蛇");

    //初始化snake
    QRectF rect(300,180,nodeWidth,nodeHeight);
    snake.append(rect);
    addTop();
    addTop();

    //初始化奖品
    addNewReward();

}

Widget::~Widget()
{
    delete ui;
}

//方向按键
void Widget::keyPressEvent(QKeyEvent *event)
{
    switch(event -> key()){
    case Qt::Key_Up:
        if(moveflag != DIR_DOWN){
            moveflag = DIR_UP;
        }
        break;
    case Qt::Key_Down:
        if(moveflag != DIR_UP){
            moveflag = DIR_DOWN;
        }
        break;
    case Qt::Key_Left:
        if(moveflag != DIR_RIGHT){
            moveflag = DIR_LEFT;
        }
        break;
    case Qt::Key_Right:
        if(moveflag != DIR_LEFT){
            moveflag = DIR_RIGHT;
        }
        break;
    case Qt::Key_Space:
        if(!blsRun)
        {
            //begin
            timer -> start(time);
        }
        else
        {
            blsRun = false;
            timer -> stop();
        }
        break;
    default:
        break;
    }
}

void Widget::timeout()
{
    //吃到了吗
    int flag = 1;
    if(snake[0].intersects(rewardNode))
    {
        flag++;
        addNewReward();
    }
    while(flag--)
    {
        switch(moveflag)
        {
            case DIR_UP:
                addTop();
                break;
            case DIR_DOWN:
                addDown();
                break;
            case DIR_RIGHT:
                addRight();
                break;
            case DIR_LEFT:
                addLeft();
                break;
            default:break;
        }

    }

    deleteLast();
    update();
}

void Widget::addTop()
{
    QPointF leftTop;
    QPointF rightBottom;

    if(snake[0].y() - nodeHeight < 0)
    {
        leftTop = QPointF(snake[0].x(),this -> height() - nodeHeight);
        rightBottom = QPointF(snake[0].x() + nodeWidth,this -> height());
    }
    else
    {
        leftTop = QPointF(snake[0].x(),snake[0].y()-nodeHeight);
        rightBottom = snake[0].topRight();
    }


    snake.insert(0,QRectF(leftTop,rightBottom));

}

void Widget::addDown()
{
    QPointF leftTop;
    QPointF rightBottom;

    if(snake[0].y() - nodeHeight * 2 > this -> height())
    {
        leftTop = QPointF(snake[0].x(),0);
        rightBottom = QPointF(snake[0].x() + nodeWidth, nodeHeight);
    }
    else
    {
        leftTop = snake[0].bottomLeft();
        rightBottom = snake[0].bottomRight() + QPointF(0,nodeHeight);
    }


    snake.insert(0,QRectF(leftTop,rightBottom));

}

void Widget::addLeft()
{
    QPointF leftTop;
    QPointF rightBottom;

    if(snake[0].x() - nodeWidth < 0 )
    {
        leftTop = QPointF(this -> width() - nodeWidth,snake[0].y());
    }
    else
    {
        leftTop = snake[0].topLeft() - QPointF(nodeWidth,0);
    }

    rightBottom = leftTop + QPointF(nodeWidth,nodeHeight);

    snake.insert(0,QRectF(leftTop,rightBottom));

}

void Widget::addRight()
{
    QPointF leftTop;
    QPointF rightBottom;

    if(snake[0].x() + nodeWidth * 2 > this->width())
    {
        leftTop = QPointF(0,snake[0].y());
    }
    else
    {
        leftTop = snake[0].topRight();
    }

    rightBottom = leftTop + QPointF(nodeWidth,nodeHeight);

    snake.insert(0,QRectF(leftTop,rightBottom));

}

//绘制
void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QPen pen;
    QBrush brush;

//    QPixmap pix;
//    pix.load("C:\Users\29737\Desktop\OIP-C.jpg");
//    painter.drawPixmap(0,,0,600,368.pix);

    //1.snake
    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[i]);
    }

    //2.reward
    pen.setColor(Qt::black);
    brush.setColor(Qt::red);
    brush.setStyle(Qt::SolidPattern);
    painter.setPen(pen);
    painter.setBrush(brush);
    painter.drawEllipse(rewardNode);

    if(checkContact())
    {
        QFont font("黑体",30,QFont::ExtraLight,false);
        painter.setFont(font);
        painter.drawText(this->width()-300 / 2,
                         this->height()-30 / 2,
                         QString("GAME OVER"));
        timer->stop();
    }

    QWidget::paintEvent(event);

}

void Widget::deleteLast()
{
    snake.removeLast();
}

void Widget::addNewReward()
{
    rewardNode = QRectF(
                qrand()%(this->width()/20) * 20,
                qrand()%(this->height()/20) * 20,
                nodeWidth,
                nodeHeight);
}

bool Widget::checkContact()
{
    for(int j = 0;j < snake.length();j++)
    {
        for(int i = j+1;i < snake.length();i++)
        {
            if(snake[j] == snake[i])
            {
                return 1;
            }
        }
    }

    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值