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();
}
*/


浙公网安备 33010602011771号