当前位置: 首页 > news >正文

在ubuntu上用QT写一个简单的C++小游戏

最近老师让用Qt写一个可视化界面,然后就给了一个小视频,好奇的不得了,就照着做了一下
视频链接如下:C++案例教学–一个类游戏小程序的设计与实现全过程–用到QT-简单的STL容器


创建项目

1、打开QT
如果不知道怎么下载的话,可以参考这篇文章

在这里插入图片描述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即可生效。

相关文章:

  • linux 安装dotnet sdk
  • git Husky 搭配 commitizen ,规范代码提交
  • 【数据结构与算法】排序算法总结
  • 拒绝宕机,华为云CDN赋能企业发展!
  • redis 的五大数据类型及其常用命令
  • 【从零开始游戏开发】EmmyLua插件注解功能
  • 最新CUDA/cuDNN与Pytorch保姆级图文安装教程(速查字典版)
  • 赶紧进来看看---万字博客详解C/C++中的动态内存管理
  • 【Python编程】九、Python文件操作
  • 今天面了个阿里拿27k出来的小哥,让我见识到了什么是天花板
  • 基于python/django的图书管理系统
  • “帆软杯”武汉大学2022级新生程序设计竞赛
  • C语言中的文件操作那些事儿~~
  • 百度地图API的使用(附案例)
  • 一小时快速入门MyBatis(知识结构清晰)
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • go append函数以及写入
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • JavaScript异步流程控制的前世今生
  • js算法-归并排序(merge_sort)
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • php的插入排序,通过双层for循环
  • 闭包,sync使用细节
  • 二维平面内的碰撞检测【一】
  • 好的网址,关于.net 4.0 ,vs 2010
  • 基于游标的分页接口实现
  • 京东美团研发面经
  • zabbix3.2监控linux磁盘IO
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​人工智能书单(数学基础篇)
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • # centos7下FFmpeg环境部署记录
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (二)JAVA使用POI操作excel
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (蓝桥杯每日一题)love
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • .helper勒索病毒的最新威胁:如何恢复您的数据?
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .net 简单实现MD5
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout
  • .NET设计模式(11):组合模式(Composite Pattern)
  • .net下的富文本编辑器FCKeditor的配置方法
  • .NET性能优化(文摘)
  • .NET序列化 serializable,反序列化
  • .net中应用SQL缓存(实例使用)
  • .pop ----remove 删除
  • /etc/fstab 只读无法修改的解决办法
  • @Autowired和@Resource装配