C++ Qt 待机弹球游戏

news2024/11/15 14:05:13

以前的电视机待机时,都有一个球在界面弹来弹去,碰到边界则改变颜色和方向。

设计算法实现该效果,qt实现界面,C++实现运动轨迹,及颜色变化。

详细注释

效果如图

 运动轨迹控制类头文件

#ifndef CMOTIONCONTROL_H
#define CMOTIONCONTROL_H

#include <vector>
#include <string>

/**
 * @brief  坐标信息结构体
 * @author GGX
 * @date   2023-08-13
 */
struct SPoint
{
    int x;
    int y;

    /**
     * @brief  重载操作符
     * @param  [in] point 自增信息
     * @return 无
     * @author GGX
     * @date   2023-08-13
     */
    SPoint & operator+=(SPoint point)
    {
        x += point.x;
        y += point.y;
        return *this;
    }

    /**
     * @brief  判断X是否在范围内
     * @param  [in] lX 范围左区间
     * @param  [in] rX 范围右区间
     * @return  true 在范围内,false不在范围内
     * @author GGX
     * @date   2023-08-13
     */
    bool isRangeX(int lX, int rX)
    {
        return x > lX && x < rX;
    }

    /**
     * @brief  判断Y是否在范围内
     * @param  [in] lY 范围左区间
     * @param  [in] rY 范围右区间
     * @return  true 在范围内,false不在范围内
     * @author GGX
     * @date   2023-08-13
     */
    bool isRangeY(int lY, int rY)
    {
        return y > lY && y < rY;
    }
};

/**
 * @brief  弹球控制类
 * @author GGX
 * @date   2023-08-13
 */
class CMotionControl
{
public:
    CMotionControl();

    /**
     * @brief  设置坐标位置
     * @param  [in] x 坐标轴
     * @param  [in] y 坐标轴
     * @return 无
     * @author GGX
     * @date   2023-08-13
     */
    void setPoint(int x, int y);

    /**
     * @brief  获取坐标位置
     * @param  无
     * @return SPoint 坐标位置
     * @author GGX
     * @date   2023-08-13
     */
    SPoint getPoint();

    /**
     * @brief  设置范围右区间
     * @param  [in] x 坐标轴
     * @param  [in] y 坐标轴
     * @return SPoint 坐标位置
     * @author GGX
     * @date   2023-08-13
     */
    void setRange(int x, int y);

    /**
     * @brief  设置步进值
     * @param  [in] SPoint x,y步进值
     * @return 无
     * @author GGX
     * @date   2023-08-13
     */
    void setStep(SPoint step);

    /**
     * @brief  在坐标范围内移动弹球位置
     * @param  [in] SPoint x,y步进值
     * @return 无
     * @author GGX
     * @date   2023-08-13
     */
    bool move();

    /**
     * @brief  获取弹球颜色
     * @param  无
     * @return std::string 弹球颜色
     * @author GGX
     * @date   2023-08-13
     */
    std::string color();

    /**
     * @brief  获取弹球边框颜色
     * @param  无
     * @return std::string 弹球边框颜色
     * @author GGX
     * @date   2023-08-13
     */
    std::string borderColor();

protected:
    /**
     * @brief  初始化弹球颜色
     * @param  无
     * @return 无
     * @author GGX
     * @date   2023-08-13
     */
    void initColor();

private:
    SPoint m_Point;     //弹球位置
    SPoint m_Range;     //范围右区间
    SPoint m_Step;      //步进值

    size_t m_indexColor;    //当前弹球颜色
    std::vector<std::string> m_colors;  //弹球颜色容器
};

#endif // CMOTIONCONTROL_H

运动轨迹控制类源文件

#include "cmotioncontrol.h"

CMotionControl::CMotionControl()
{
    m_Point = {0, 0};
    m_Range = {0, 0};
    m_Step  = {0, 0};

    initColor();
}

void CMotionControl::setPoint(int x, int y)
{
    m_Point = {x, y};
}

SPoint CMotionControl::getPoint()
{
    return m_Point;
}

void CMotionControl::setRange(int x, int y)
{
    m_Range = {x, y};
}

void CMotionControl::setStep(SPoint step)
{
    m_Step = step;
}

bool CMotionControl::move()
{
    //弹球是否碰壁
    bool bChange = false;

    if (!m_Point.isRangeX(0, m_Range.x))
    {
        //若是超出范围,则按反方向移动
        m_Step.x = -m_Step.x;
        bChange = true;
    }

    if (!m_Point.isRangeY(0, m_Range.y))
    {
        //若是超出范围,则按反方向移动
        m_Step.y = -m_Step.y;
        bChange = true;
    }

    if (bChange)
    {
        //弹球碰壁,则变换颜色
        m_indexColor++;
    }

    if (m_indexColor >= m_colors.size())
    {
        m_indexColor = 0;
    }

    //弹球位置移动
    m_Point += m_Step;
    return bChange;
}

std::string CMotionControl::color()
{
    return m_colors.at(m_indexColor);
}

std::string CMotionControl::borderColor()
{
    return m_colors.at(m_colors.size() - m_indexColor - 1);
}

void CMotionControl::initColor()
{
    m_indexColor = 0;

//    m_colors.emplace_back("color0");
//    m_colors.emplace_back("color1");
    m_colors.emplace_back("black");
    m_colors.emplace_back("white");
    m_colors.emplace_back("darkGray");
    m_colors.emplace_back("gray");
    m_colors.emplace_back("lightGray");
    m_colors.emplace_back("red");
    m_colors.emplace_back("green");
    m_colors.emplace_back("blue");
    m_colors.emplace_back("darkGray");
    m_colors.emplace_back("cyan");
    m_colors.emplace_back("magenta");
    m_colors.emplace_back("yellow");
    m_colors.emplace_back("darkRed");
    m_colors.emplace_back("darkGray");
    m_colors.emplace_back("darkGreen");
    m_colors.emplace_back("darkBlue");
    m_colors.emplace_back("darkCyan");
    m_colors.emplace_back("darkMagenta");
    m_colors.emplace_back("darkYellow");
//    m_colors.emplace_back("transparent");
}

QT界面头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <qtimer.h>

class CMotionControl;

namespace Ui
{
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void slTimer();

    void on_start_clicked();

private:
    Ui::MainWindow *ui;

    int m_step;             //每次移动的像素

    CMotionControl *m_pMotionControl; //控制弹球运动轨迹及颜色
    QTimer      *m_pTimer;  //定时器,触发移动
};

#endif // MAINWINDOW_H

QT界面源文件

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "qdebug.h"
#include "cmotioncontrol.h"

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

    m_pTimer = new QTimer(this);
    connect(m_pTimer, SIGNAL(timeout()), this, SLOT(slTimer()));

    m_step = 10;
    m_pMotionControl = new CMotionControl();
    m_pMotionControl->setStep({m_step, m_step});
}

MainWindow::~MainWindow()
{
    delete ui;
    delete m_pTimer;
    delete m_pMotionControl;
}

void MainWindow::slTimer()
{
    //移动弹球坐标
    bool bChange = m_pMotionControl->move();
    //获取移动后的位置
    SPoint point = m_pMotionControl->getPoint();
    //移动弹球
    ui->label_point->move(point.x, point.y);

    //弹球碰壁则改变颜色
    if (bChange)
    {
        QString bgColor = m_pMotionControl->color().c_str();
        QString bdColor = m_pMotionControl->borderColor().c_str();

        int length = 100;
        QString strColor = "";
        strColor.append(QString("min-width:%1px;").arg(length));
        strColor.append(QString("min-height:%1px;").arg(length));
        strColor.append(QString("max-width:%1px;").arg(length));
        strColor.append(QString("max-height:%1px;").arg(length));
        strColor.append(QString("border-radius:%1px;").arg(length / 2));
        strColor.append(QString("border:%1px solid %2;").arg(3).arg(bdColor));
        strColor.append(QString("background-color:%1;").arg(bgColor));

        ui->label_point->setStyleSheet(QString("QLabel{%1}").arg(strColor));  //设置样式表
    }

    qDebug() << "SPoint: {" << point.x << ", " << point.y << "}";
}

void MainWindow::on_start_clicked()
{
    //设置弹球起点
    m_pMotionControl->setPoint(ui->label_point->pos().x(),
                               ui->label_point->pos().y());

    //设置弹球范围
    m_pMotionControl->setRange(width() - ui->label_point->width() - m_step,
                               height() - ui->label_point->height() - m_step);
    int msec = 50;
    //启停定时器
    if (m_pTimer->isActive())
    {
        m_pTimer->stop();
    }
    else
    {
        m_pTimer->start(msec);
    }
}

码云地址:svn://gitee.com/gongguixing/daily-learning/qt_ui/Pinball

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/902014.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

系统架构设计师之网络安全-各个层次的网络安全保障

系统架构设计师之网络安全-各个层次的网络安全保障

java面试基础 -- ArrayList 和 LinkedList有什么区别, ArrayList和Vector呢?

目录 基本介绍 有什么不同?? ArrayList的扩容机制 ArrayLIst的基本使用 ArrayList和Vector 基本介绍 还记得我们的java集合框架吗, 我们来复习一下, 如图: 可以看出来 ArrayList和LinkedList 都是具体类, 他们都是接口List的实现类. 但是他们底层的逻辑是不同的, 相信…

什么是条件get方法?

条件GET方法通常指的是HTTP协议中的"GET"请求&#xff0c;但它带有一些条件&#xff0c;这些条件用于控制服务器是否应该返回请求的资源。这些条件通常使用HTTP标头字段来指定&#xff0c;以便客户端可以告诉服务器在某些条件下是否需要新的或更新的资源。 条件GET方…

操作符详解下(非常详细)

这里写目录标题 下标访问[ ]、函数调用()[ ]下标引用操作符函数调用操作符 操作符的属性&#xff1a;优先级、结合性优先级结合性 表达式求值整型提升整型提升的意义如何进行整体提升 算术转换问题表达式解析表达式1表达式2表达式3表达式4表达式5 总结 下标访问[ ]、函数调用()…

第3天----在一行句子中寻找最长最短单词

今天我们将学习如何在一行句子中寻找(第一次出现的)最长最短单词。本节内容会或多或少地利用到第一讲/第二讲的知识点&#xff0c;需要的同学可以先去看看前面的内容。 一、小试牛刀&#xff1a; 题目描述 输入 1 行句子&#xff08;不多于 200 个单词&#xff0c;每个单词长度…

股票交易这个游戏玩法的本质

养家老师的“买在分歧&#xff0c;卖在一致”不用过度解读了&#xff0c;这句话也会是一个人入门标志&#xff0c;那就是这个市场是博弈的市场&#xff0c;预期打满没有任何分歧的话&#xff0c;那就没有继续博弈的价值了&#xff0c;也就只有最后一批接盘的人&#xff0c;而分…

Java程序设计——编写一个登录页面

需要编写两个类 LonginFrame、MainFrame LonginFrame类 import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class LoginFrame extends JFrame {JLabel lbluserLogIn;JL…

GitLab与GitLab Runner安装(RPM与Docker方式),CI/CD初体验

背景 GitLab 是一个强大的版本控制系统和协作平台&#xff0c;记录一下在实际工作中关于 GitLab 的安装使用记录。 一开始使用 GitLab 时&#xff0c;是在 CentOS7 上直接以 rpm 包的方式进行安装&#xff0c;仅作为代码托管工具来使用&#xff0c;版本&#xff1a; 14.10.4 …

OpenCV基础知识(6)— 滤波器

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。在尽量保留原图像信息的情况下&#xff0c;去除图像内噪声、降低细节层次信息等一系列过程&#xff0c;被叫做图像的平滑处理&#xff08;或者叫图像的模糊处理&#xff09;。实现平滑处理最常用的工具就是滤波器。通过调节…

对容器、虚拟机和 Docker 的初学者友好介绍

一、说明 如果你是一个程序员或技术人员&#xff0c;你可能至少听说过Docker&#xff1a;一个有用的工具&#xff0c;用于在“容器”中打包&#xff0c;运输和运行应用程序。很难不这样做&#xff0c;这些天它得到了所有的关注 - 来自开发人员和系统管理员。即使是像谷歌、VMwa…

idea gerrit 插件使用指引

IDEA安装gerrit插件 在线安装&#xff08;推荐&#xff09; 直接搜索gerrit&#xff0c;安装即可离线安装 可以到github下载离线包&#xff1a;https://github.com/uwolfer/gerrit-intellij-plugin/releases&#xff0c;不过可能会有版本不兼容问题&#xff0c;还是推荐在线安装…

完美版积分商城系统-奇偶商城系统源码+独立代理后台

奇偶商城系统源码 完美版独立代理后台 1.演示环境&#xff1a;Linux Centos7以上版本 宝塔 2.Nginx 1.18.0 PHP7.0 Mysql5.6 3.伪静态选择thinkphp 4./Application/Common/Conf 修改数据库信息 详细搭建教程附在压缩包内了,下载查看

信号量

信号量&#xff08;semaphore&#xff09;和信号只有一字之差&#xff0c;却是不同的概念&#xff0c;信号量与之前介绍的IPC不同&#xff0c;它是一个计数器&#xff0c;用于实现进程间的互斥于同步 本文参考&#xff1a; Linux 的信号量_linux 信号量_行孤、的博客-CSDN博客 …

常见的 Python 错误及其解决方案

此文整理了一些常见的 Python 错误及其解决方案。 1、SyntaxError: invalid syntax 说明&#xff1a;无效的语法是最常见的错误之一&#xff0c;通常是由于编写代码时违反了 Python 的语法规则。可能的原因&#xff1a; 忘记在 if、while、for 等语句后写冒号&#xff0c;或者…

perl下载与安装教程【工具使用】

Perl是一个高阶程式语言&#xff0c;由 Larry Wall和其他许多人所写&#xff0c;融合了许多语言的特性。它主要是由无所不在的 C语言&#xff0c;其次由 sed、awk&#xff0c;UNIX shell 和至少十数种其他的工具和语言所演化而来。Perl对 process、档案&#xff0c;和文字有很强…

GAN!生成对抗网络GAN全维度介绍与实战

目录 一、引言1.1 生成对抗网络简介1.2 应用领域概览1.3 GAN的重要性 二、理论基础2.1 生成对抗网络的工作原理2.1.1 生成器生成过程 2.1.2 判别器判别过程 2.1.3 训练过程训练代码示例 2.1.4 平衡与收敛 2.2 数学背景2.2.1 损失函数生成器损失判别器损失 2.2.2 优化方法优化代…

windows批处理set命令:设置变量,计算表达式

文章目录 基础模式表达式模式变量输入模式环境变量 基础模式 变量是一切编程的基础&#xff0c;在批处理语言中&#xff0c;通过set设置变量&#xff0c;而在调用变量时&#xff0c;需要在变量两端加上百分号&#xff0c;例如 set a1 echo %a%运行结果为 >set a1 >ech…

离市区太远的高铁站,导致旅客舍弃高铁而转用其他交通工具

随着高铁网络的完善&#xff0c;如今旅客出行越来越多选择快速、便捷的高铁作为出行交通工具&#xff0c;不过旅客显然也对一些城市的高铁站离市区太远有所抱怨&#xff0c;导致不少消费者选择舍弃高铁而转用其他交通工具。 网上有一份高铁站离市区距离的排名&#xff0c;据悉离…

Linux Xshell常用命令

一、查看服务器信息 1.1、查看CentOS服务器版本号 执行以下命令 cat /etc/redhat-release结果如下&#xff1a; 1.2、查看服务器根目录下空间占用情况 执行以下命令 cd / du -h --max-depth1 |grep G |sort参数说明&#xff1a; –max-depth1 最大深度为1 grep ‘G’ 文…

JavaScript中的this关键字的作用,以及它如何确定其值

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ this关键字的作用⭐ this的值取决于执行上下文⭐ 示例⭐ 总结⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这…