最近老师让用Qt写一个可视化界面,然后就给了一个小视频,好奇的不得了,就照着做了一下
 视频链接如下:C++案例教学–一个类游戏小程序的设计与实现全过程–用到QT-简单的STL容器
创建项目
1、打开QT
 如果不知道怎么下载的话,可以参考这篇文章
 2、在这里可以修改项目的名字和保存位置
2、在这里可以修改项目的名字和保存位置

 3、之后就按照默认的,一直按[next]就可以了
 
 
 
 
 
 
代码如下
开始写代码了,具体操作老师在视频里全都说明了,这里只附上代码,希望对不想敲代码的朋友有帮助
 
 以下这些代码都是自动生成后修改过的代码
 ballobject.h
#ifndef BALLOBJECT_H
#define BALLOBJECT_H
#include <string>
#include <random>
//需要一些ball的共有属性和方法
class BaseBall
{
public:
    BaseBall();
    virtual ~BaseBall();
    int x, y;//位置
    int r;//半径
    virtual void LiveOneTimeSlice()=0;//存活在一个时间片里面
    virtual std::string GetClassName()
    {
        return "BaseBall";
        //获取对象所属的类的名字
    };
};
class PassiveBall :public BaseBall
{
public:
    PassiveBall():BaseBall(){};
    void LiveOneTimeSlice() override;
    std::string GetClassName() override;
};
class PlayerBall : public PassiveBall
{
public:
    PlayerBall():PassiveBall(){};
    std::string GetClassName() override;
};
class RandomMoveBall :public BaseBall
{
public:
    RandomMoveBall():BaseBall(){};
    void LiveOneTimeSlice() override;
    std::string GetClassName() override;
};
#endif // BALLOBJECT_H
mainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <vector>
#include "ballobject.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private:
    Ui::MainWindow *ui;
    QTimer *timer;
    std::vector<BaseBall*> objList;//障碍物列表
    PlayerBall *playerball;//玩家来控制的小球
    void paintEvent(QPaintEvent *);
    void keyPressEvent(QKeyEvent *ev);
    void TimerEvent();
};
#endif // MAINWINDOW_H
ballobject.cpp
#include "ballobject.h"
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(0,100);
BaseBall::BaseBall()
{
    x = y = 0;
    r = 30;
}
BaseBall::~BaseBall()
{
}
void PassiveBall::LiveOneTimeSlice()
{
}
std::string PassiveBall::GetClassName()
{
    return "PassiveBall";
}
std::string PlayerBall::GetClassName()
{
    return "PlayerBall";
}
void RandomMoveBall::LiveOneTimeSlice()
{
    bool bLeft = distribution(generator)>49;
    x = bLeft ?x-20:x+20;
    bool bUp = distribution(generator)>49;
    y = bUp?y-10:y+10;
}
std::string RandomMoveBall::GetClassName()
{
    return "RandomMoveBall";
}
mainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>
#include <QTimer>
#include "ballobject.h"
#include <QDebug>
#include <QKeyEvent>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //设定定时器Timer,每秒刷新30次,FPS=30,大概是三十毫秒
    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &MainWindow::TimerEvent);
    timer->start(50);
    //创建游戏对象1
    int objectsNum = 10;
    int H = this->height();
    int W = this->width();
    int xstep = (W - objectsNum*20)/(objectsNum-1);
    for(int i = 0;i < objectsNum;i++)
    {
        PassiveBall* obj = new PassiveBall();
        //排放障碍物
        obj->x=i*(obj->r*2 + xstep)+obj->r;
        obj->y=H/2;
        obj->r=10;
        objList.push_back(obj);
    }
    //创建游戏对象2
    for(int i = 0;i < objectsNum;i++)
    {
        RandomMoveBall* obj = new RandomMoveBall();
        //排放障碍物
        obj->x=i*(obj->r*2 + xstep)+obj->r;
        obj->y=H/2 - 20;
        obj->r=20;
        objList.push_back(obj);
    }
    //创建游戏对象3
    for(int i = 0;i < objectsNum;i++)
    {
        RandomMoveBall* obj = new RandomMoveBall();
        //排放障碍物
        obj->x=i*(obj->r*2 + xstep)+obj->r;
        obj->y=H/2 - 20;
        obj->r=20;
        objList.push_back(obj);
    }
    //初始化玩家位置TODO
    playerball = new PlayerBall();
    playerball->x = W/2;
    playerball->y = H;
    playerball->r=10;
}
MainWindow::~MainWindow()
{
    delete ui;
    delete timer;//不删除就会内存泄露
    for(auto itm:objList)
    {
        delete itm;
    }
    delete playerball;
}
void MainWindow::paintEvent(QPaintEvent *)
{
//    static int x = 0;
//    QPainter painter(this);
//    painter.setPen(Qt::red);
//    painter.setFont(QFont("楷体", 50));
//    painter.drawText(rect(), Qt::AlignCenter, "我爱你中国");
//    painter.setPen(Qt::blue);
//    painter.setFont(QFont("楷体",500));
//    painter.drawEllipse(x,0,100,100);
//    x+=20;
    //给每一个游戏对象存活一个时间片
    for(auto itm:objList)
    {
        itm->LiveOneTimeSlice();
    }
    //绘制整个游戏场景
    QPainter painter(this);
    painter.setPen(Qt::black);
    for(auto itm:objList)
    {
        QBrush brush(QColor(0,200,250),Qt::Dense4Pattern);
        painter.setBrush(brush);
        painter.drawEllipse(itm->x-itm->r,itm->y-itm->r,itm->r*2,itm->r*2);
    }
    painter.setPen(Qt::darkBlue);
    QBrush brush(QColor(250,20,80),Qt::Dense4Pattern);
    painter.setBrush(brush);
    painter.drawEllipse(playerball->x-playerball->r,playerball->y-playerball->r,playerball->r*2,playerball->r*2);
}
void MainWindow::keyPressEvent(QKeyEvent *ev)
{
    if(ev->key()==Qt::Key_Up)
    {
        playerball->y-=10;
        qDebug()<<"Press Key Up";
        return ;
    }
    if(ev->key()==Qt::Key_Down)
    {
        playerball->y+=10;
        qDebug()<<"Press Key Down";
        return ;
    }
    if(ev->key()==Qt::Key_Left)
    {
        playerball->x-=10;
        qDebug()<<"Press Key Left";
        return ;
    }
    if(ev->key()==Qt::Key_Right)
    {
        playerball->x+=10;
        qDebug()<<"Press Key Right";
        return ;
    }
}
void MainWindow::TimerEvent()
{
    //还要判断失败
    for(auto itm:objList)
    {
        float distSqure = (itm->x - playerball->x)*(itm->x - playerball->x)+
                (itm->y - playerball->y)*(itm->y - playerball->y);
        if(distSqure<=((itm->r + playerball->r)*(itm->r + playerball->r)))
        {
            qDebug() <<"Failed!";
            timer->stop();
        }
    }
    //判断成功
    if(playerball->y <= 0)
    {
        qDebug() <<"Success!";
        timer->stop();
    }
    update();
}
效果如下

 
 按动键盘上的上下左右键可以控制红色小球从下面往上跑,在不碰到蓝色小球的情况下安全到达最上方就挑战成功啦~
一点小问题
如果你下载的QTcreator版本在6以上,很有可能不能输入中文,虽然可以输出,如果是6以下的版本,可以采用一下方法修改配置,使其可以输入中文。
由Qt开发的软件界面不能输入中文
 安装fcitx-libs-qt或fcitx-libs-qt5,在计算机中搜索libfcitxplatforminputcontextplugin.so文件,例如在我的计算机上,此文件位于
/usr/lib/x86_64-linux-gnu/qt5/plugins/platforminputcontexts/libfcitxplatforminputcontextplugin.so
找到Qt的安装目录,将上述文件复制到安装目录下的plugins/platforminputcontexts子目录下。
 重新运行程序即可。
QtCreator本身的编辑器不能输入中文
 如果是QtCreator本身编辑器不能输入中文,则将上述文件拷贝至Qt安装目录的[Qt安装目录]/Tools/QtCreator/lib/Qt/plugins/platforminputcontexts或者[Qt安装目录]/Tools/QtCreator/bin/plugins/platforminputcontexts。
 对于不同版本的Qt,插件路径可能略有不同,但一定是在[Qt安装目录]/Tools/QtCreator/中,可以自己搜索一下。拷贝完成后,重新启动QtCreator即可生效。
看了老师的视频就知道老师想要实现一个HuntPlayerBall去追踪玩家,但是由于时间的限制没能实现,那我这个垃圾实现了更简单的功能,希望老师看到了不要嫌弃。
代码如下
ballobject.h
#ifndef BALLOBJECT_H
#define BALLOBJECT_H
#include <string>
#include <random>
//需要一些ball的共有属性和方法
class BaseBall
{
public:
    BaseBall();
    virtual ~BaseBall();
    int x, y;//位置
    int r;//半径
    virtual void LiveOneTimeSlice()=0;//存活在一个时间片里面
    virtual std::string GetClassName()
    {
        return "BaseBall";
        //获取对象所属的类的名字
    };
};
class PassiveBall :public BaseBall
{
public:
    PassiveBall():BaseBall(){};
    void LiveOneTimeSlice() override;
    std::string GetClassName() override;
};
class PlayerBall : public PassiveBall
{
public:
    PlayerBall():PassiveBall(){};
    std::string GetClassName() override;
};
class RandomMoveBall :public BaseBall
{
public:
    RandomMoveBall():BaseBall(){};
    void LiveOneTimeSlice() override;
    std::string GetClassName() override;
};
class HuntPlayerBall :public BaseBall
{
public:
    HuntPlayerBall():BaseBall(){};
    void LiveOneTimeSlice() override;
    std::string GetClassName() override;
};
#endif // BALLOBJECT_H
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <vector>
#include "ballobject.h"
#include <random>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private:
    Ui::MainWindow *ui;
    QTimer *timer;
    std::vector<BaseBall*> objList1;//障碍物列表
    std::vector<BaseBall*> objList2;//障碍物列表
    std::vector<BaseBall*> objList3;//障碍物列表
    PlayerBall *playerball;//玩家来控制的小球
    void paintEvent(QPaintEvent *);
    void keyPressEvent(QKeyEvent *ev);
    void TimerEvent();
};
#endif // MAINWINDOW_H
ballobject.cpp
#include "ballobject.h"
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(0,100);
BaseBall::BaseBall()
{
    x = y = 0;
    r = 30;
}
BaseBall::~BaseBall()
{
}
void PassiveBall::LiveOneTimeSlice()
{
}
std::string PassiveBall::GetClassName()
{
    return "PassiveBall";
}
std::string PlayerBall::GetClassName()
{
    return "PlayerBall";
}
void RandomMoveBall::LiveOneTimeSlice()
{
    bool bLeft = distribution(generator)>49;
    x = bLeft ?x-10:x+10;
    bool bUp = distribution(generator)>49;
    y = bUp?y-10:y+10;
}
std::string RandomMoveBall::GetClassName()
{
    return "RandomMoveBall";
}
void HuntPlayerBall::LiveOneTimeSlice()
{
    bool bLeft = distribution(generator)>49;
    x = bLeft ?x-20:x+20;
    bool bUp = distribution(generator)>49;
    y = bUp?y-10:y+10;
}
std::string HuntPlayerBall::GetClassName()
{
     return "HuntPlayerBall";
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>
#include <QTimer>
#include "ballobject.h"
#include <QDebug>
#include <QKeyEvent>
#include <math.h>
#include <QRandomGenerator>
//添加随机数种子,作用:利用当前系统时间生成随机数,以此来防止每一次的随机数相同
#include <ctime> //添加头文件
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //设定定时器Timer,每秒刷新30次,FPS=30,大概是三十毫秒
    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &MainWindow::TimerEvent);
    timer->start(50);
//    start = new QTimer(this);
//    connect(start, &QTimer::timeout, this, &MainWindow::StartEvent);
    //创建游戏对象1
    int objectsNum = 10;
    int H = this->height();
    int W = this->width();
    int xstep = (W - objectsNum*20)/(objectsNum-1);
    for(int i = 0;i < 30;i++)
    {
        PassiveBall* obj = new PassiveBall();
        //排放障碍物
        int bLeft = QRandomGenerator::global()->bounded(100,1200);
        //qDebug()<<bLeft;
        obj->x=bLeft;
        int bRight = QRandomGenerator::global()->bounded(100,1200);
       //qDebug()<<bRight;
        obj->y=bRight;
        obj->r=15;
        objList1.push_back(obj);
    }
    //创建游戏对象2
    for(int i = 0;i < objectsNum;i++)
    {
        RandomMoveBall* obj = new RandomMoveBall();
        //排放障碍物
        obj->x=i*(obj->r*2 + xstep)+obj->r;
        obj->y=H/2 - 20;
        obj->r=20;
        objList2.push_back(obj);
    }
    //创建游戏对象3
    for(int i = 0;i < objectsNum;i++)
    {
        HuntPlayerBall* obj = new HuntPlayerBall();
        //排放障碍物srand
        obj->x=i*(obj->r*2 + xstep)+obj->r;
        obj->y=H/2 - 20;
        obj->r=10;
        objList3.push_back(obj);
    }
    //初始化玩家位置TODO
    playerball = new PlayerBall();
    playerball->x = W/2;
    playerball->y = H;
    playerball->r=10;
}
MainWindow::~MainWindow()
{
    delete ui;
    delete timer;//不删除就会内存泄露
    for(auto itm:objList1)
    {
        delete itm;
    }
    for(auto itm:objList2)
    {
        delete itm;
    }
    for(auto itm:objList3)
    {
        delete itm;
    }
    delete playerball;
}
void MainWindow::paintEvent(QPaintEvent *)
{
//    static int x = 0;
//    QPainter painter(this);
//    painter.setPen(Qt::red);
//    painter.setFont(QFont("楷体", 50));
//    painter.drawText(rect(), Qt::AlignCenter, "我爱你中国");
//    painter.setPen(Qt::blue);
//    painter.setFont(QFont("楷体",500));
//    painter.drawEllipse(x,0,100,100);
//    x+=20;
    //给每一个游戏对象存活一个时间片
    for(auto itm:objList1)
    {
        itm->LiveOneTimeSlice();
    }
    for(auto itm:objList2)
    {
        itm->LiveOneTimeSlice();
    }
    for(auto itm:objList3)
    {
        itm->LiveOneTimeSlice();
    }
    //绘制整个游戏场景
    QPainter painter(this);
    painter.setPen(Qt::black);
    for(auto itm:objList1)
    {
        QBrush brush(QColor(0,200,0),Qt::Dense4Pattern);
        painter.setBrush(brush);
        painter.drawEllipse(itm->x-itm->r,itm->y-itm->r,itm->r*2,itm->r*2);
    }
    for(auto itm:objList2)
    {
        QBrush brush(QColor(0,200,250),Qt::Dense4Pattern);
        painter.setBrush(brush);
        painter.drawEllipse(itm->x-itm->r,itm->y-itm->r,itm->r*2,itm->r*2);
    }
    for(auto itm:objList3)
    {
        QBrush brush(QColor(250,20,20),Qt::Dense4Pattern);
        painter.setBrush(brush);
        painter.drawEllipse(itm->x-itm->r,itm->y-itm->r,itm->r*2,itm->r*2);
    }
    painter.setPen(Qt::darkBlue);
    QBrush brush(QColor(255,255,0),Qt::Dense4Pattern);
    painter.setBrush(brush);
    painter.drawEllipse(playerball->x-playerball->r,playerball->y-playerball->r,playerball->r*2,playerball->r*2);
}
void MainWindow::keyPressEvent(QKeyEvent *ev)
{
    if(ev->key()==Qt::Key_Up)
    {
        playerball->y-=30;
        qDebug()<<"Press Key Up";
        return ;
    }
    if(ev->key()==Qt::Key_Down)
    {
        playerball->y+=30;
        qDebug()<<"Press Key Down";
        return ;
    }
    if(ev->key()==Qt::Key_Left)
    {
        playerball->x-=30;
        qDebug()<<"Press Key Left";
        return ;
    }
    if(ev->key()==Qt::Key_Right)
    {
        playerball->x+=30;
        qDebug()<<"Press Key Right";
        return ;
    }
}
void MainWindow::TimerEvent()
{
    //还要判断失败
    for(auto itm:objList1)
    {
        float distSqure = (itm->x - playerball->x)*(itm->x - playerball->x)+
                (itm->y - playerball->y)*(itm->y - playerball->y);
        if(distSqure<=((itm->r + playerball->r)*(itm->r + playerball->r)))
        {
            qDebug() <<"Failed!";
            timer->stop();
        }
    }
    for(auto itm:objList2)
    {
        float distSqure = (itm->x - playerball->x)*(itm->x - playerball->x)+
                (itm->y - playerball->y)*(itm->y - playerball->y);
        if(distSqure<=((itm->r + playerball->r)*(itm->r + playerball->r)))
        {
            qDebug() <<"Failed!";
            timer->stop();
        }
    }
    for(auto itm:objList3)
    {
        float distSqure = (itm->x - playerball->x)*(itm->x - playerball->x)+
                (itm->y - playerball->y)*(itm->y - playerball->y);
        if(distSqure<=((itm->r + playerball->r)*(itm->r + playerball->r)))
        {
            qDebug() <<"Failed!";
            timer->stop();
        }
    }
    for(auto itm:objList3)
    {
        float distSqure = sqrt((itm->x - playerball->x)*(itm->x - playerball->x)+
                (itm->y - playerball->y)*(itm->y - playerball->y));
        if(distSqure<=(itm->r + playerball->r+200))
        {
            float x_dis=(playerball->x - itm->x)/distSqure;
            float y_dis=(playerball->y - itm->y)/distSqure;
            itm->x+=x_dis*10;
            itm->y+=y_dis*10;
        }
    }
    //判断成功
    if(playerball->y <= 0)
    {
        qDebug() <<"Success!";
        timer->stop();
    }
    update();
}
效果如下
红色小球会追踪,顺便绿色小球每次编译刷新
















![【精选】ARMv8/ARMv9架构入门到精通-[前言]](http://assets.processon.com/chart_image/604719347d9c082c92e419de.png)



