QT实现猜数字游戏


环境: QT5 linux
主要知识点: QLable显示图片、动图;常用控件的使用;信号与槽复习;在QTextEdit显示不同颜色字体、并且能够实现回车换行效果;使用QStackedWidget实现四个页面切换;定时器的使用等

实现效果:

  • 刚进入游戏前设置固定时间,进入游戏后由进度条显示剩余时间;
  • 代码生成一个随机数,随机数种子基于当前时间而定,范围在1000到10000;
  • 当用户输入数字时,会实时显示输入内容在左侧文本框,检测不能输入0为开头的数,并且输入的数为4位数后自动检测答案,按键里还设置了删除功能、正确结果显示;
  • 每次输入的结果都会往下自动叠加;
  • 当猜测的数字正确,则成功,显示动图;
  • 当时间超时还未能猜测出来,则失败,显示失败动图;同时在动图里设置了继续游戏或退出游戏选项

MyWidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>
#include <QMovie>

namespace Ui {
class MyWidget;
}

class MyWidget : public QWidget
{
    Q_OBJECT

public:
    explicit MyWidget(QWidget *parent = 0);
    ~MyWidget();

    //自定义槽函数
    void dealNum();

public slots:
    void go_On_Game();
    void exit_from_Game();

private slots:
    void on_pushButtonStart_clicked();

    void on_pushButtonDel_clicked();

    void on_pushButtonEnter_clicked();

protected:
    //定时器事件,此为虚函数
    void timerEvent(QTimerEvent *e);

private:
    Ui::MyWidget *ui;
    int gameTime;       //游戏时间
    QString randStr;    //随机数
    int gameTimerId;    //游戏时间定时器ID
    int overTimerId;    //失败动画定时器ID
    int winTimerId;     //成功动画定时器ID
    QString resultStr;  //结果数
    QString tmpResultStr;

    QMovie overMovie;   //失败动画
    QMovie winMovie;    //胜利动画


};

#endif // MYWIDGET_H


MyWidget.cpp

#include "mywidget.h"
#include "ui_mywidget.h"
#include <QDebug>
#include <QTime>
#include <QMessageBox>
#include <QString>
#include <QLabel>

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

    //显示第一个页面(设置页面)
    //ui->stackedWidget->setCurrentIndex(0);
    ui->stackedWidget->setCurrentWidget(ui->pageSet);

    //初始化数据
    //失败动画
    overMovie.setFileName(":/new/prefix1/Image/over.gif");
    ui->labelOver->setMovie(&overMovie);//给标签设置动画
    ui->labelOver->setScaledContents(true);//让动画自动适应标签大小

    //胜利动画
    winMovie.setFileName(":/new/prefix1/Image/win.gif");
    ui->labelWin->setMovie(&winMovie);
    ui->labelWin->setScaledContents(true);

    //猜数字游戏界面相应设置
    //数字按钮都连接同一个槽
    connect(ui->pushButton0, &QPushButton::clicked, this, &MyWidget::dealNum);
    connect(ui->pushButton1, &QPushButton::clicked, this, &MyWidget::dealNum);
    connect(ui->pushButton2, &QPushButton::clicked, this, &MyWidget::dealNum);
    connect(ui->pushButton3, &QPushButton::clicked, this, &MyWidget::dealNum);
    connect(ui->pushButton4, &QPushButton::clicked, this, &MyWidget::dealNum);
    connect(ui->pushButton5, &QPushButton::clicked, this, &MyWidget::dealNum);
    connect(ui->pushButton6, &QPushButton::clicked, this, &MyWidget::dealNum);
    connect(ui->pushButton7, &QPushButton::clicked, this, &MyWidget::dealNum);
    connect(ui->pushButton8, &QPushButton::clicked, this, &MyWidget::dealNum);
    connect(ui->pushButton9, &QPushButton::clicked, this, &MyWidget::dealNum);
}

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

//开始游戏
void MyWidget::on_pushButtonStart_clicked()
{
    //获取下拉框的时间 .toInt():字符串转换为 int
    gameTime = ui->spinBox->text().toInt();

    //切换到游戏界面
    //ui->stackedWidget->setCurrentIndex(1);
    ui->stackedWidget->setCurrentWidget(ui->pageGame);

    int num;
    //以从0时0分0秒到现在的秒数为种子
    qsrand( QTime(0,0,0).secsTo( QTime::currentTime() ) );
    //调用全局的qrand()函数生成随机数,对10000取余,保证位于10000的范围内
    while( ( num = qrand()%10000 ) < 999 );//1000到10000
    randStr = QString::number(num);//转成字符串形式

    //设置进度条
    ui->progressBar->setMinimum(0);//最小值
    ui->progressBar->setMaximum(gameTime);//最大值
    ui->progressBar->setValue(gameTime); //当前值

    gameTimerId = 0;
    //启动定时器
    gameTimerId = startTimer(1000); //以 1000 毫秒(即1s)作为时间间隔

    resultStr.clear();
    tmpResultStr = "<font color=\"Orange\">已设置 "+QString::number(gameTime)+ " s, Game Start!</font>";
    ui->textEdit->setText(tmpResultStr);

    connect(ui->pushButtonStart_1,SIGNAL(clicked()),this,SLOT(go_On_Game()));
    connect(ui->pushButtonStart_2,SIGNAL(clicked()),this,SLOT(go_On_Game()));
    connect(ui->pushButtonEnd_1,SIGNAL(clicked()),this,SLOT(exit_from_Game()));
    connect(ui->pushButtonEnd_2,SIGNAL(clicked()),this,SLOT(exit_from_Game()));
}

void MyWidget::go_On_Game()
{
    ui->stackedWidget->setCurrentWidget(ui->pageSet);
}
void MyWidget::exit_from_Game()
{
    this->close(); //关闭窗口
}

void MyWidget::timerEvent(QTimerEvent *e)
{
    if(e->timerId() == gameTimerId)//游戏时间
    {
        gameTime--;

        //设置进度条
        ui->progressBar->setValue(gameTime); //当前值

        if(0 == gameTime)//时间到
        {
            //关闭定时器
            killTimer(gameTimerId);

            QMessageBox::information(this, "失败", "时间到了啊!!!");


            overMovie.start();//启动动画

            //切换失败动画页面
            //ui->stackedWidget->setCurrentIndex(2);
            ui->stackedWidget->setCurrentWidget(ui->pageOver);

            overTimerId = startTimer(15000); //启动定时器

        }

    }
    else if(e->timerId() == overTimerId)//失败动画时间
    {
        //停止动画,停止定时器,回到游戏设置页面
        overMovie.stop();//停止动画
        killTimer(overTimerId);  //停止定时器

        //切换到游戏设置页面
        ui->stackedWidget->setCurrentWidget(ui->pageSet);

    }
    else if(e->timerId() == winTimerId)//胜利动画时间
    {

        winMovie.stop();//停止动画
        killTimer(winTimerId);  //停止定时器

        //切换到游戏设置页面
        ui->stackedWidget->setCurrentWidget(ui->pageSet);

    }
}

//数字键处理
void MyWidget::dealNum()
{
    //获取信号接收者
    QObject * mySender = sender();
    //转换为按钮类型
    QPushButton *p = (QPushButton *)mySender;
    if(NULL != p)
    {
        //获取按钮的内容
        QString numStr = p->text();
        resultStr += numStr;

        //数字不能以0开始
        if(resultStr.size() == 1 && resultStr == "0")
        {
            resultStr.clear();
        }

        if( resultStr.size() <= 4) //保证显示结果为4位
        {
             ui->textEdit->setText( resultStr );
             ui->textEdit->append(  "<br />"+tmpResultStr);

             if(resultStr.size() == 4) //数字到第4位时
             {
                 if(resultStr > randStr)
                 {
                     ui->textEdit->clear();
                     QString tmp = "<font color=\"Red\">数字 "+resultStr+" 数字大了点!!!<br /></font>";
                     ui->textEdit->setText(tmp);
                     ui->textEdit->append( tmpResultStr );
                     // <br /> 为换行,如果用\r\n是不行的
                     tmpResultStr = tmp + tmpResultStr;
                 }
                 else if(resultStr < randStr)
                 {
                     ui->textEdit->clear();
                     QString tmp = "<font color=\"Blue\">数字 "+resultStr+" 数字小了点!!!<br /></font>";
                     ui->textEdit->setText(tmp);
                     ui->textEdit->append( tmpResultStr );
                     tmpResultStr = tmp + tmpResultStr;
                 }
                 else
                 {
                     ui->textEdit->setText("恭喜你猜对了!!!");

                     //停止定时器
                     //关闭定时器
                     killTimer(gameTimerId);

                     QMessageBox::information(this, "胜利", "恭喜你猜对了!!!");

                     //切换到成功动画
                     winMovie.start();
                     ui->stackedWidget->setCurrentWidget(ui->pageWin);

                     //启动定时器
                     winTimerId = startTimer(15000); //5s
                 }

                 //初始化字符串结果,清空
                 resultStr.clear();
             }
        }

    }

}

//退格按钮,删除后一个数字
void MyWidget::on_pushButtonDel_clicked()
{
    resultStr.chop(1);//截断最后一位字符
    ui->textEdit->setText(resultStr);
    ui->textEdit->append(  "<br />"+tmpResultStr);

}

//提示按钮
void MyWidget::on_pushButtonEnter_clicked()
{
    resultStr.clear();
    QString str = "正确答案为:" + randStr;
    ui->textEdit->setText( str );
}


完整工程代码链接:
链接:https://pan.baidu.com/s/1zP70ZXL1IilzwKfLNZ32vA
提取码:d353


猜你喜欢

转载自blog.csdn.net/fengge2018/article/details/106411326