QT入门(五)——贪吃蛇游戏的实现

本文详细介绍了使用QT开发贪吃蛇游戏的过程,包括游戏效果展示、widge及gamewidge头文件和源代码,还有主要的widget和main函数的实现,最后讲解了UI界面设计的两个关键部分:gamewidget.ui和widget.ui。
摘要由CSDN通过智能技术生成

目录

1.游戏效果展示

 2.widge.h

3.gamewidge.h

4.gamewidget.cpp

5.widget.cpp

6.main.cpp

7.UI 界面设计

7.1gamewidget.ui

 7.2widget.ui


1.游戏效果展示

 2.widge.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QPainter>
#include"gamewidget.h"
#include<QDebug>
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    void init();
    void initWindow();
    void initBackground();
    void paintEvent(QPaintEvent *e);

    void clear();
    ~Widget();

private slots:
    void on_StartButton_clicked();
    void on_CloseButton_clicked();

private:
    Ui::Widget *ui;
     QPixmap m_pix;
};

#endif // WIDGET_H

3.gamewidge.h

#ifndef GAMEWIDGET_H
#define GAMEWIDGET_H

#include <QWidget>
#include<QPalette>
#include<QPainter>
#include<QRect>
#include<QMessageBox>
#include<QTimer>
#include<QKeyEvent>
#include<QPixmap>
#include<QDebug>
#define COL 20  //列
#define ROW  20 //行
#define RECTWIDTH 30
#define RECTHIGHT 30
namespace Ui {
class GameWidget;
}

class GameWidget : public QWidget
{
    Q_OBJECT

public:
    explicit GameWidget(QWidget *parent = 0);
    void paintEvent(QPaintEvent *e);
    void init();
    void initWindow();
    void initConnect();
    void Clear();
    void DrawSnakeHead();
    void initBackground();
    void Upgrade() ;//升级操作
    void FlashScore();
    void CreateFood(); //开始创建食物
    void SnakeHeadRun();  //蛇头开始运行
    void CheckEatFood();
    void TimeOutSlots();//结束的条件判断
    void GameOver();
    void keyPressEvent(QKeyEvent *e);


    enum EmDirection //定义一个枚举,表示前后左右移动
    {
      emUp = 0,
      emDown,
      emLeft,
      emRight
    };

    ~GameWidget();

private slots:
    void on_quitButton_clicked();

    void on_UpButton_clicked();

    void on_DownButton_clicked();

    void on_LeftButton_clicked();

    void on_RightButton_clicked();

    void on_continueButton_clicked();

    void on_stopButton_clicked();



private:
    Ui::GameWidget *ui;
    int FoodPosition[2]; //食物的位置
    int Snake[100][2];   //存储一条蛇型(食物)的容器 ,s[0][]一直作为蛇头存在
    int m_FoodCount;     //食物数量
    int m_CurrentSpeed;  //更新速度
    int m_CurrentGrade;  //分数
    int m_UpgradeScore;   //第一次升级所需要分数
    int  m_Direction;    //蛇头行进方向判断
    QPixmap m_pax;
    QTimer *timer;  //设计定时器
    QPixmap m_pax1;
    QPixmap m_pax2;
};

#endif // GAMEWIDGET_H

4.gamewidget.cpp

#include "gamewidget.h"
#include "ui_gamewidget.h"

GameWidget::GameWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::GameWidget)
{
     ui->setupUi(this);
     qDebug()<<"helloworld111";
     setFocusPolicy(Qt::StrongFocus);  //使键盘光标锁定在你所画的界面内
     m_pax1.load("G:/picture/basketball.webp");
     m_pax2.load("G:/picture/green.webp");
    init();
    qDebug()<<"helloworld";
    m_pax.load("G:/picture/111.webp");
    CreateFood();

}

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

void GameWidget::Clear()
{
    timer=new QTimer;
    m_CurrentSpeed=300;
    DrawSnakeHead();
    m_UpgradeScore = 50;
    m_CurrentGrade=1;
    m_FoodCount=4;
}

void GameWidget::DrawSnakeHead() //设置蛇头坐标的随机值
{
    Snake[0][0] = qrand() % COL;
    Snake[0][1] = qrand() % ROW;
    m_Direction = qrand() % 4;
}

void GameWidget::paintEvent(QPaintEvent *e)
{
    //1.显示背景图片
    QPainter painter(this);
    painter.drawPixmap(this->rect(),m_pax);

    //2.画游戏盘
    for(int x=0;x<COL;x++)
    {
        for(int y=0;y<ROW;y++)
        {
            QRect rect(x*RECTWIDTH,y*RECTHIGHT,RECTWIDTH,RECTHIGHT);
            painter.drawRect(rect);
        }
    }

    //画食物
    QRect FoodRect(FoodPosition[0]*RECTWIDTH,FoodPosition[1]*RECTHIGHT,RECTWIDTH,RECTHIGHT);
    painter.drawPixmap(FoodRect,m_pax1);
    //painter.fillRect(FoodRect,Qt::green);

    //画蛇头
    QRect HeadRect(Snake[0][0]*RECTWIDTH,Snake[0][1]*RECTHIGHT,RECTWIDTH,RECTHIGHT);
    //painter.fillRect(HeadRect,Qt::red);
    painter.drawPixmap(HeadRect,m_pax2);
    //画蛇身
    for(int i=1;i<=m_FoodCount;++i)
    {
        QRect BodyRect(Snake[i][0]*RECTWIDTH,Snake[i][1]*RECTHIGHT,RECTWIDTH,RECTHIGHT);
        //painter.fillRect(BodyRect,Qt::red);
        painter.drawPixmap(BodyRect,m_pax1);
    }


}

void GameWidget::init()
{
    Clear();
    initWindow();
    initBackground();
    initConnect();

}

void GameWidget::initWindow()
{
    this->setWindowTitle("贪吃蛇");
    this->setWindowIcon(QIcon("G:/picture/snake.webp"));
}

void GameWidget::initConnect()
{
    connect(timer,&QTimer::timeout,this,&GameWidget::TimeOutSlots);
    timer->start(m_CurrentSpeed);
}

void GameWidget::initBackground()
{
    setAutoFillBackground(true);
    QPalette palete;
    palete.setBrush(QPalette::Background,QBrush(QPixmap("G:/picture/111.webp")));
    setPalette(palete);
//    ui->quitButton->setIcon(QIcon("G:\\picture\\green.webp"));
//    ui->quitButton->setIconSize(QSize(50,50));
//    ui->quitButton->setFlat(true);
}

void GameWidget::GameOver() //游戏结束时,我们需要做的操作
{
    timer->stop();  //关闭定时器
    QMessageBox::information(this,"提示","游戏结束");  //窗口提示,游戏结束
    ui->LevellineEdit->setText("1");     //将等级分数置为原始数据
    ui->ScorelineEdit->setText("0");
    this->close();
}

void GameWidget::Upgrade() //升级操作
{
    if(ui->ScorelineEdit->text().toInt() >= m_UpgradeScore)//当所得分数大于(当前等级 * 第一次要升级的分数)
    {
        m_UpgradeScore *= 2;  //需要前一次的基础分数*2 ,才鞥升级
        ++m_CurrentGrade;  //等级+1
        if(m_CurrentSpeed > 50) //最高速度为50,
        {
            m_CurrentSpeed -= 50;  //更新速度提高
        }
        timer->stop();    //定时器停止进行提示
        QMessageBox::information(this,"提示","升级成功,进入下一级");
        CreateFood();
        timer->start(m_CurrentSpeed);  //定时器重新开始,并且以m_CurrentSpeed时间,刷新一次界面

    }
}

void GameWidget::FlashScore() //更新分数与等级
{
    ui->LevellineEdit->setText(QString::number(m_CurrentGrade));
    ui->ScorelineEdit->setText(QString::number(m_FoodCount *10)); //一个食物设成10分
}

void GameWidget::CreateFood() //开始创建食物
{
    FoodPosition[0] = qrand() % COL;
    FoodPosition[1] = qrand() % ROW;
    //防止食物产生在蛇上
    for(int i = 0 ; i <= m_FoodCount;i++)
    {
        if(FoodPosition[0] == Snake[i][0] && FoodPosition[1] == Snake[i][1])
        {
            FoodPosition[0] = qrand() % COL +1;
            FoodPosition[1] = qrand() % ROW +1;
        }
    }
}

void GameWidget::SnakeHeadRun()  //蛇头开始运行
{
    switch (m_Direction) {
    case emUp:
        --Snake[0][1]; //纵坐标-1
        break;
    case emDown:
        ++Snake[0][1];  //纵坐标+1
        break;
    case emLeft:
        --Snake[0][0];  //横坐标-1;
        break;
    case emRight:
        ++Snake[0][0];  //横坐标+1
        break;
    default:
        break;
    }
}

void GameWidget::CheckEatFood() //吃到食物之后的操作
{
    if(Snake[0][0] == FoodPosition[0] && Snake[0][1] == FoodPosition[1])//当蛇头与食物相重合时,表示已经吃到
    {
        ++m_FoodCount; //食物数+1
        Upgrade();     //判断是否升级
        FlashScore();  //更新分数和等级
        CreateFood();  //在创建一个食物
    }
    //蛇身体的移动
    for(int SnId = m_FoodCount; SnId > 0;--SnId)
    {
        Snake[SnId][0] = Snake[SnId - 1][0];
        Snake[SnId][1] = Snake[SnId - 1][1];
    }
    SnakeHeadRun();  //头部继续运行

}

void GameWidget::TimeOutSlots()//结束的条件判断
{
//    if(Snake[0][0] > (COL -1) || Snake[0][0] <0 || Snake[0][1] < 0 || Snake[0][1] > (ROW - 1))
//    {
//        GameOver();
//    }
    if(Snake[0][0] > (COL -1))
    {
        Snake[0][0] = 0;
    }
    else if(Snake[0][0] <0)
    {
        Snake[0][0] = COL - 1;
    }
    else if(Snake[0][1] < 0)
    {
        Snake[0][1] = ROW - 1;
    }
    else if(Snake[0][1] > (ROW - 1))
    {
        Snake[0][1] = 0;
    }
    for(int i = 1;i <= m_FoodCount;i++)//当蛇头与蛇身一部分重合时,结束
    {
        if(Snake[0][0] == Snake[i][0] && Snake[0][1] == Snake[i][1])
        {
            GameOver();
        }
    }
    CheckEatFood();  //执行判断食物是否吃到食物
    update();    //调用paintEvent事件函数,刷新界面
}


void GameWidget::on_quitButton_clicked()
{
    this->close();
}

void GameWidget::on_UpButton_clicked()
{
    if(m_Direction != emDown)
    {
        m_Direction = emUp;
    }
}

void GameWidget::on_DownButton_clicked()
{
    if(m_Direction != emUp)
    {
        m_Direction = emDown;
    }
}

void GameWidget::on_LeftButton_clicked()
{
    if(m_Direction != emRight)
    {
      m_Direction = emLeft;
    }
}

void GameWidget::on_RightButton_clicked()
{
    if(m_Direction != emLeft)
    {
        m_Direction = emRight;
    }

}

void GameWidget::keyPressEvent(QKeyEvent *e)
{
    if(e->key() == Qt::Key_Left)
    {
        on_LeftButton_clicked();
    }
    else if(e->key() == Qt::Key_Right)
    {
        on_RightButton_clicked();
    }
    else if(e->key() == Qt::Key_Up)
    {
        on_UpButton_clicked();
    }
    else if(e->key() == Qt::Key_Down)
    {
        on_DownButton_clicked();
    }
}


void GameWidget::on_continueButton_clicked()
{
    timer->start(m_CurrentSpeed);  //定时器重新开始,并且以m_CurrentSpeed时间,刷新一次界面
}

void GameWidget::on_stopButton_clicked()
{
    timer->stop();    //定时器停止进行提示
    QMessageBox::information(this,"提示","已暂停");
}

5.widget.cpp

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

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

   // this->setWindowFlags(Qt::Window|Qt::FramelessWindowHint);
    m_pix.load("G:/picture/bardground.webp");
    init();
}

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

void Widget::paintEvent(QPaintEvent *e)
{
    QPainter painter(this);
    QRect rc =rect();
    painter.drawPixmap(rc,m_pix);
}

void Widget::init()
{
    initWindow();
    initBackground();
}

void Widget::initWindow()
{
    setWindowTitle("强强版定制贪吃蛇游戏");
    QIcon con("G:/picture/snake.webp");
    this->setWindowIcon(con);
}

void Widget::initBackground()
{
    setAutoFillBackground(true);
    QPalette palete;
    palete.setBrush(QPalette::Background,QBrush(QPixmap("G:/picture/bardground.webp")));
    setPalette(palete);

    ui->StartButton->setIcon(QIcon("G:/picture/start.webp"));
    ui->StartButton->setIconSize(QSize(100,100));
    ui->StartButton->setFlat(true);



    ui->CloseButton->setIcon(QIcon("G:/picture/close.webp"));
    ui->CloseButton->setIconSize(QSize(100,100));
    ui->CloseButton->setFlat(true);
}

void Widget::on_StartButton_clicked()
{
    GameWidget*widget=new GameWidget(this);
     qDebug()<<"helloworld111";
    widget->show();
    qDebug()<<"helloworld2221";

}

void Widget::on_CloseButton_clicked()
{
    this->close();
}

6.main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

7.UI 界面设计

7.1gamewidget.ui

 7.2widget.ui

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李 同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值