qt 实现泡泡特效

使用deepseek写的代码

#include <QWidget>
#include <QPainter>
#include <QTimer>
#include <QTime>
#include <cmath>
#include <vector>
#include <cstdlib> // 添加cstdlib头文件
#include <ctime>   // 添加ctime头文件

class Bubble {
public:
    QPointF position;
    QPointF velocity;
    double size;
    QColor color;
    double opacity;
    double life; // 0.0-1.0
    double rotation;
    double rotationSpeed;

    Bubble(int width, int height)
    {
        // 初始化随机种子
        std::srand(std::time(nullptr));

        // 使用qrand替代QRandomGenerator
        size = 15.0 + static_cast<double>(qrand() % 45); // 15-60
        opacity = 0.4 + static_cast<double>(qrand() % 50) / 100.0; // 0.4-0.9
        life = 1.0;
        rotation = 0;
        rotationSpeed = -2.0 + static_cast<double>(qrand() % 400) / 100.0; // -2.0-2.0

        position = QPointF(static_cast<double>(qrand() % width),
                   height + size);

        double speed = 1.0 + static_cast<double>(qrand() % 200) / 100.0; // 1.0-3.0
        velocity = QPointF(-0.5 + static_cast<double>(qrand() % 100) / 100.0, -speed);

        // 创建蓝色调的泡泡
        int blue = 150 + qrand() % 105;
        int green = 100 + qrand() % 155;
        color = QColor(100, green, blue, static_cast<int>(opacity * 255));
    }

    void update() {
        position += velocity;
        life -= 0.002; // 逐渐消失
        rotation += rotationSpeed;

        // 添加轻微的左右摆动
        velocity.setX(velocity.x() + (-0.1 + static_cast<double>(qrand() % 200) / 1000.0));

        // 限制最大摆动幅度
        if (velocity.x() > 0.8) velocity.setX(0.8);
        if (velocity.x() < -0.8) velocity.setX(-0.8);
    }

    bool isDead() const { return life <= 0.0; }
};

class BubbleWidget : public QWidget {
public:
    BubbleWidget(QWidget *parent = nullptr)
        : QWidget(parent)
    {
        // 初始化随机种子
        std::srand(std::time(nullptr));
        qsrand(QTime::currentTime().msec());

        setWindowTitle("蓝色背景泡泡动效");
        resize(1000, 700);
        setMouseTracking(true);

        // 设置定时器刷新界面
        QTimer *timer = new QTimer(this);
        connect(timer, &QTimer::timeout, this, [this]() {
            updateBubbles();
            update(); // 触发重绘
        });
        timer->start(16); // ~60 FPS

        // 初始化粒子
        bubbles.reserve(50);

        // 创建渐变背景
        background = QLinearGradient(0, 0, width(), height());
        background.setColorAt(0.0, QColor(10, 40, 100));
        background.setColorAt(1.0, QColor(5, 20, 50));
    }

protected:
    void paintEvent(QPaintEvent *) override {
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.setRenderHint(QPainter::SmoothPixmapTransform, true);

        // 绘制渐变背景
        painter.fillRect(rect(), background);

        // 绘制装饰性水波
        drawWaterRipples(painter);

        // 绘制所有泡泡
        for (const auto& bubble : bubbles) {
            drawBubble(painter, bubble);
        }

        // 绘制标题
        drawTitle(painter);
    }

    void resizeEvent(QResizeEvent *event) override {
        QWidget::resizeEvent(event);
        // 更新背景渐变
        background = QLinearGradient(0, 0, width(), height());
        background.setColorAt(0.0, QColor(10, 40, 100));
        background.setColorAt(1.0, QColor(5, 20, 50));
    }

private:
    void drawBubble(QPainter& painter, const Bubble& bubble) {
        painter.save();
        painter.translate(bubble.position);
        painter.rotate(bubble.rotation);

        QColor bubbleColor = bubble.color;
        bubbleColor.setAlphaF(bubble.opacity * bubble.life);

        // 绘制泡泡主体
        QRadialGradient radialGrad(0, 0, bubble.size * 0.8);
        radialGrad.setColorAt(0.0, Qt::white);
        radialGrad.setColorAt(0.3, bubbleColor.lighter(150));
        radialGrad.setColorAt(1.0, bubbleColor);

        painter.setBrush(radialGrad);
        painter.setPen(Qt::NoPen);
        painter.drawEllipse(QPointF(0, 0), bubble.size, bubble.size);

        // 绘制高光
        painter.setBrush(Qt::white);
        painter.setOpacity(0.4 * bubble.life);
        painter.drawEllipse(QPointF(-bubble.size*0.3, -bubble.size*0.3),
                           bubble.size*0.3, bubble.size*0.3);

        painter.restore();
    }

    void drawWaterRipples(QPainter& painter) {
        painter.setPen(QPen(QColor(100, 180, 255, 80), 2));
        painter.setBrush(Qt::NoBrush);

        QTime time = QTime::currentTime();
        double offset = time.msec() / 1000.0 * 2 * M_PI;

        for (int i = 0; i < 5; i++) {
            double radius = 100 + i * 30 + sin(offset * 0.8 + i) * 10;
            painter.drawEllipse(QPointF(width()/2, height()/2), radius, radius);
        }

        // 绘制底部水波
        painter.setPen(QPen(QColor(100, 180, 255, 120), 3));
        for (int i = 0; i < 10; i++) {
            double y = height() - 50 + i * 5;
            double amplitude = sin(offset * 2 + i * 0.5) * 15;
            QPainterPath path;
            path.moveTo(0, y);
            for (int x = 0; x < width(); x += 10) {
                double wave = sin(x * 0.03 + offset * 3 + i) * amplitude;
                path.lineTo(x, y + wave);
            }
            path.lineTo(width(), y);
            painter.drawPath(path);
        }
    }

    void drawTitle(QPainter& painter) {
        QFont titleFont("Arial", 36, QFont::Bold);
        painter.setFont(titleFont);

        QLinearGradient titleGradient(0, 0, width(), 0);
        titleGradient.setColorAt(0.0, Qt::white);
        titleGradient.setColorAt(0.5, QColor(180, 230, 255));
        titleGradient.setColorAt(1.0, Qt::white);

        painter.setPen(QPen(titleGradient, 2));
        painter.setBrush(Qt::NoBrush);

        QRect titleRect(0, 50, width(), 100);
        painter.drawText(titleRect, Qt::AlignCenter, "蓝色海洋泡泡效果");

        // 绘制副标题
        QFont subFont("Arial", 16);
        painter.setFont(subFont);
        painter.setPen(QPen(QColor(200, 230, 255), 1));
        painter.drawText(QRect(0, height()-80, width(), 40), Qt::AlignCenter, "泡泡数量: " + QString::number(bubbles.size()));
    }

    void updateBubbles() {
        // 添加新泡泡
        if (bubbles.size() < 50 && (qrand() % 100) < 20) {
            bubbles.emplace_back(width(), height());
        }

        // 更新泡泡状态
        for (auto& bubble : bubbles) {
            bubble.update();
        }

        // 移除死亡泡泡
        bubbles.erase(
            std::remove_if(bubbles.begin(), bubbles.end(),
                [](const Bubble& b) { return b.isDead() || b.position.y() < -b.size; }),
            bubbles.end());
    }

    QLinearGradient background;
    std::vector<Bubble> bubbles;
};

/*
#include <QApplication>

#include "particlewidget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    BubbleWidget w; w.show();

    return a.exec();
}
*/

posted @ 2025-06-04 19:22  小城熊儿  阅读(21)  评论(0)    收藏  举报