QT贪吃蛇

widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include<QPainter>
#include<QIcon>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
 
    setWindowTitle("贪吃蛇");
    setFixedSize(600,360);
    setWindowIcon(QIcon(":/img/snake.png"));
 
    // 使用定时器
    timer = new QTimer();
    // 信号槽
    connect(timer,SIGNAL(timeout()),this,SLOT(timeout()));
    //设置窗口大小
    resize(600,368);
 
    //初始化蛇身
    QRectF rect(300,180,nodewidth,nodeheight);
    snake.append(rect);
    addTop();
    addTop();
    //初始化奖品
    addNewReword();
}
 
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_Right:
        if(moveFlag != DIR_LEFT){
        moveFlag = DIR_RIGHT;
        }
        break;
    case Qt::Key_Left:
        if(moveFlag!=DIR_RIGHT){
        moveFlag = DIR_LEFT;
        }
        break;
    case Qt::Key_Space:
        if(!gamestart){
            gamestart = true;
            //启动定时器
            timer->start(time);
        }
        else {
            gamestart = false;
            timer->stop();
        }
        break;
    default:
        break;
    }
}
 
void Widget::timeout()
{
    int count = 1;
    //判断有没有重合
    if(snake[0].intersects(rewardNode)){
        count++;
        addNewReword();
    }
    while(count--) {
        switch (moveFlag) {
         case DIR_UP:
             //顶部加一个方块尾部删一个
             addTop();
             break;
         case DIR_DOWN:
            addDown();
            break;
         case DIR_LEFT:
            addLeft();
            break;
         case DIR_RIGHT:
            addRight();
            break;
         default:
          break;
         }
    }
 
    deleteLast();
    update();
 
}
 
void Widget::addTop()
{
    QPointF lefttop;
    QPointF rightbotom;
 
    if(snake[0].y()-nodeheight < 0)
    {
        lefttop=QPoint(snake[0].x(),this->height()-nodeheight);
        rightbotom = QPointF(snake[0].x()+nodewidth,this->height());
    }
    else {
        lefttop = QPointF(snake[0].x(),snake[0].y()-nodeheight);
        rightbotom = snake[0].topRight();
    }
 
 
    snake.insert(0,QRectF(lefttop,rightbotom));
}
 
void Widget::addDown()
{
    QPointF lefttop;
    QPointF rightbotom;
 
    if(snake[0].y()+nodeheight+nodeheight >  this->height()){
        lefttop = QPointF(snake[0].x(),0);
        rightbotom = QPointF(snake[0].x()+nodewidth,nodeheight);
    }else {
        lefttop = snake[0].bottomLeft();
        rightbotom = snake[0].bottomRight()+QPointF(0,nodeheight);
    }
    snake.insert(0,QRectF(lefttop,rightbotom));
}
 
void Widget::addLeft()
{
    QPointF lefttop;
    QPointF rightbotom;
 
    if(snake[0].x()-nodewidth<0){
        lefttop = QPointF(this->width()-nodewidth,snake[0].y());
    } else {
        lefttop = snake[0].topLeft()-QPointF(nodewidth,0);
    }
    rightbotom = lefttop+QPointF(nodewidth,nodeheight);
    snake.insert(0,QRectF(lefttop,rightbotom));
}
 
void Widget::addRight()
{
    QPointF lefttop;
    QPointF rightbotom;
    if(snake[0].x()+nodewidth+nodewidth>this->width()){
        lefttop = QPointF(0,snake[0].y());
    } else {
        lefttop = snake[0].topRight();
    }
    rightbotom = lefttop+QPointF(nodewidth,nodeheight);
    snake.insert(0,QRectF(lefttop,rightbotom));
}
 
void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QPen pen;
    QBrush brush;
 
    //设置背景图片
    QPixmap pix;
    pix.load("D:/Picture/aa.jpg");
    painter.drawPixmap(0,0,600,368,pix);
 
    //画蛇
    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]);
    }
 
    //画奖品
    pen.setColor(Qt::red);
    brush.setColor(Qt::red);
    brush.setStyle(Qt::SolidPattern);   //实心填充
    painter.setPen(pen);
    painter.setBrush(brush);
    //painter.drawRect(rewardNode);
    painter.drawEllipse(rewardNode);
 
    if(checkcontact()){
            pen.setColor(Qt::black);
            QFont font("微软雅黑",30,QFont::ExtraLight,false);
            painter.setFont(font);
            painter.setPen(pen);
            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::addNewReword()
{
    rewardNode = QRectF(
                qrand()%(this->width()/20)*20,
                qrand()%(this->height()/20)*20,
                nodewidth,nodeheight);
}
 
bool Widget::checkcontact()
{
    for(int i=0;i<snake.length();i++)
        for(int j=i+1;j<snake.length();j++)
        {
            if(snake[i] == snake[j])
            {
                return true;
            }
    }
 
    return false;
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include <QKeyEvent>
#include<QTimer>
 
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
 
//蛇的表示
    //
// 按键处理
// 使用定时器
    //关联信号槽
    //启动定时器
    //实现槽函数
// 渲染
 
enum Direc{
    DIR_LEFT,
    DIR_RIGHT,
    DIR_UP,
    DIR_DOWN
};
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
 
protected:
    //渲染,绘图
    void paintEvent(QPaintEvent *event);
 
    void addTop();
    void addDown();
    void addLeft();
    void addRight();
 
    void addNewReword();
    bool checkcontact();
    //按键处理
    void keyPressEvent(QKeyEvent *event);
 
    //删除小方块
    void deleteLast();
 
private:
    Ui::Widget *ui;
    int moveFlag = DIR_UP;
    bool gamestart = false;
    //定时器
    QTimer *timer;
    int time=100;   //超时时间,毫秒
    //蛇的表示
    QList <QRectF> snake;     //QRectF表示一块区域
    //奖品
    QRectF rewardNode;
    //小方块宽高
    int nodewidth = 20;
    int nodeheight = 20;
 
protected slots:   //槽函数
    void timeout();
};
#endif // WIDGET_H
main.cpp
#include "widget.h"
 
#include <QApplication>
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

                
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值