QML粒子系统

一、前言

粒子系统用于模拟一些特定的模糊效果,例如:爆炸、烟花、雪花、水流等。使用传统的渲染技术实现粒子效果比较困难,但是使用QML粒子系统能十分方便的实现各种粒子效果,使你的界面更加炫酷、动感。


二、QML中的粒子系统

QML粒子系统的核心是ParticleSystem,用于控制共享时间线。一个场景可以有多个粒子系统,每一个都有自己独立的时间线。

粒子由粒子发射器(Emitter)元素发射,使用粒子画笔(ParticlePainter)进行可视化显示,它可以是一张图片、一个QML项或者一个着色器程序。Emitter还使用向量空间定义了粒子方向,粒子一旦发射,就脱离了Emitter的控制。

粒子模块提供了粒子控制器(Affector),它可以控制已发射粒子的参数。

系统中的粒子可以通过粒子组(ParticleGroup)共享时间变换,默认情况下,粒子都属于空组。

粒子系统主要类如下

功能
ParticleSystem粒子系统,管理发射器共享时间线
Emitter粒子发射器,向系统中发射逻辑粒子
ParticlePainter粒子画笔,使用粒子画笔绘制粒子
Direction方向,已发出粒子使用的空间向量
ParticleGroup粒子组,每个粒子都是一个粒子组的成员
Affector粒子控制器,控制已发射的粒子

三、粒子系统-ParticleSystem

ParticleSystem用于控制共享时间线,它将ParticleSystemEmitterAffector等元素联合起来实现粒子效果,也就是说其它类型想要交互的话就必须在同一个ParticleSystem中。

想要使用粒子系统,第一步就是要创建一个粒子系统:

import QtQuick.Particles 2.0

ParticleSystem {
	id: particleSystem;
}

ParticleSystem包含以下属性

属性说明
empty表示系统中是否还有活着的粒子
particleStates粒子动画状态,你可以给每一个粒子组的每一个粒子使用动画精灵
paused粒子系统是否暂停
running粒子系统是否在运行

ParticleSystem提供以下方法

方法说明
void pause()暂停粒子系统
void reset()丢弃所有已经发射的粒子
void restart()停止所有粒子系统,并重新启动
void resume()当粒子系统处于暂停状态时,恢复粒子系统运行
void start()启动粒子系统
void stop()关闭粒子系统

四、粒子发射器-Emitter

Emitter向粒子系统中发射逻辑粒子,这些粒子斗殴自己的轨迹和生命周期,但它们时不可见的,想要可见的话就得用到ParticlePainter

Emitter定义了粒子的发射区域以及相关发射参数并使用system属性将自己与一个粒子系统关联起来。

想要使用粒子系统,第二步就是要创建一个粒子发射器:

import QtQuick.Particles 2.0

ParticleSystem {
	id: particleSystem;
}

Emitter {
	id: emitter;
	system: particleSystem;
}

Emitter包含以下属性

属性说明
acceleration粒子的起始加速度
emitRate发射速率(每秒发射多少个粒子,默认值为10)
enabled发射器是否使能(默认值为true)
endSize粒子什么周期结束时大小(默认值为-1)
group逻辑粒子群(默认为“”,空字符串)
lifeSpan粒子生命周期,单位毫秒(默认值为1000)
lifeSpanVariation粒子生命周期误差区间
maximumEmitted粒子最大发射量
shape粒子发射的区域(默认值为Emitter的填充矩形)
size粒子初始大小
sizeVariation粒子初始大小误差区间
startTime延迟发射时间
system粒子系统
velocity粒子发射速率
velocityFromMovement粒子的发射速率会叠加Emitter运动的速率

Emitter提供以下方法

方法说明
void burst(int count, int x, int y)立即向(x,y)点发射count个粒子
void burst(int count)立即发射count个粒子
void pulse(int duration)当发射器未启用时,零食启动发射器duration毫秒

QML还提供一个叫TrailEmitter的发射器,该发射器的特点是起始位置是基于其它粒子的,它会跟随一个粒子移动。例如你需要创建一个跟随一团火焰的烟,你可能就需要用到这个发射器。


五、粒子画笔-ParticlePainter

使用Emitter发射的只是逻辑粒子,我们还需要使用粒子画笔ParticlePainter对粒子进行可视化渲染。ParticlePainter是个基本类型,本身并不渲染任何东西,我们需要使用ParticlePainter的子类进行渲染。ParticlePainter的子类包括:ItemParticleImageParticleCustomParticle

1、ItemParticle
ItemParticle使用QML的Item来渲染粒子,我们可以给ItemParticle的delegate(代理)属性设置一个Item,这样每个粒子都会使用该Item进行渲染。同样,我们也需要使用ItemParticlesystem属性将ParticleSystemItemParticle关联起来。

import QtQuick.Particles 2.0

ParticleSystem {
	id: particleSystem;
}

Emitter {
	id: emitter;
	system: particleSystem;
}

ItemParticle {
	system: particleSystem;
	delegate: Rectangle{};
}

ItemParticle包含以下属性

属性说明
delegate将为每个逻辑粒子创建委托实例,并随之移动
fade粒子是否在生命周期结束时自动淡出或淡出

ItemParticle提供以下方法

方法说明
void freeze(Item item)暂停逻辑粒子代表的时间流,允许您控制它的移动
void give(Item item)获取Item的控制权,该Item将断开和逻辑粒子的关联
void take(Item item, bool prioritize)
void unfreeze(Item item)重新启动项目表示的逻辑粒子的时间流,允许它再次被粒子系统移动

2、ImageParticle
ImageParticle使用图像来渲染逻辑粒子,图像能够上色、旋转、变形或者添加精灵动画。

ImageParticle包含以下属性

属性说明
alpha图像的alpha值(0-1.0)
alphaVariation图像的alpha值误差区间
autoRotation自动旋转
redVariation图像红色通道变化(0-1)
greenVariation图像绿色通道变化(0-1)
blueVariation图像蓝色通道变化(0-1)
color图像颜色
colorTable纹理图像,原图像将与纹理图像混合
colorVariation图像颜色误差区间
entryEffect粒子创建和消失时的特效
opacityTable纹理图像,图像的opacity属性将与纹理图像混合
rotation图像旋转角度
rotationVariation图像旋转角度误差区间
rotationVelocity图像旋转速率
rotationVelocityVariation图像旋转速率误差区间
sizeTable纹理图像
source图像
sprites精灵动画
spritesInterpolate平滑精灵动画
status加载图像的状态
xVectorStochasticDirection
yVectorStochasticDirection

3、CustomParticle
除了ItemParticleImageParticle,还有基于着色器的粒子CustomParticleCustomParticle使用OpenGL着色器语言GLSL定义。

CustomParticle包含以下属性

属性说明
fragmentShader片段着色器
vertexShader顶点着色器

六、使用案例

1、用ItemParticle渲染粒子

在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12

import QtQuick.Particles 2.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    Rectangle {
        id: rootItem;
        width: 400;
        height: 400;
        color: "#1f1f1f";

        Rectangle {
            id: emitter_area;
            anchors.centerIn: parent;
            width: 200;
            height: 200;
            border.color: "green";
        }

        ParticleSystem {
            id: particleSystem;
        }

        Emitter {
            id: emitter;
            anchors.centerIn: parent;
            width: 200;
            height: 200;
            system: particleSystem;
            emitRate: 100;
            lifeSpan: 1000;
            lifeSpanVariation: 500;
            size: 16;
            endSize: 32;
        }

        ItemParticle {
            system: particleSystem;
            delegate: Rectangle {
                id: particleRect;
                width: 10;
                height: 10;
                color: "red";
                radius: 10;
            }
        }
    }

}
  • 矩形元素emitter_area和粒子发射器Emitter完全重合,可以看到粒子也只在这个区域内产生,说明粒子只会在粒子发射器限定的范围内产生;

2、用ImageParticle渲染粒子

在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12

import QtQuick.Particles 2.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    Rectangle {
        id: rootItem;
        width: 400;
        height: 400;
        color: "#1f1f1f";

        ParticleSystem {
            id: particleSystem;
        }

        Emitter {
            id: emitter;
            anchors.centerIn: parent;
            width: 200;
            height: 200;
            system: particleSystem;
            emitRate: 20;
            lifeSpan: 1000;
            lifeSpanVariation: 500;
            size: 16;
            endSize: 32;
        }

        ImageParticle {
            system: particleSystem;
            source: "qrc:/Sources/assets/star.png";
        }
    }

}

3、用ImageParticle渲染粒子,并设置粒子颜色

在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12

import QtQuick.Particles 2.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    Rectangle {
        id: rootItem;
        width: 400;
        height: 400;
        color: "#1f1f1f";

        ParticleSystem {
            id: particleSystem;
        }

        Emitter {
            id: emitter;
            anchors.centerIn: parent;
            width: 200;
            height: 200;
            system: particleSystem;
            emitRate: 10;
            lifeSpan: 2000;
            lifeSpanVariation: 500;
            size: 16;
            endSize: 32;
        }

        ImageParticle {
            system: particleSystem;
            source: "qrc:/Sources/assets/star.png";
            color: "#FFD700";
            colorVariation: 0.6;
        }
    }

}
  • 给粒子画笔ImageParticle设置了color为金色,颜色误差设置为0.6(颜色误差设置越靠近0误差越小,基本都是金色;颜色误差设置越靠近1误差越大,颜色越随机);

4、用ImageParticle渲染粒子,并设置粒子旋转

在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12

import QtQuick.Particles 2.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    Rectangle {
        id: rootItem;
        width: 400;
        height: 400;
        color: "#1f1f1f";

        ParticleSystem {
            id: particleSystem;
        }

        Emitter {
            id: emitter;
            anchors.centerIn: parent;
            width: 200;
            height: 200;
            system: particleSystem;
            emitRate: 10;
            lifeSpan: 2000;
            lifeSpanVariation: 500;
            size: 16;
            endSize: 32;
        }

        ImageParticle {
            system: particleSystem;
            source: "qrc:/Sources/assets/star.png";
            color: "#FFD700";
            colorVariation: 0.6;
            rotation: 15;
            rotationVariation: 5;
            rotationVelocity: 45;
            rotationVelocityVariation: 15;
        }
    }

}
  • 将每个粒子顺时针旋转15°,另外有一个5°的误差范围;
  • 将这些粒子继续以每秒45°的速度旋转,也会有一个15°的误差范围;

5、用ImageParticle渲染粒子,并设置粒子效果
在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12

import QtQuick.Particles 2.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    Rectangle {
        id: rootItem;
        width: 400;
        height: 400;
        color: "#1f1f1f";

        ParticleSystem {
            id: particleSystem;
        }

        Emitter {
            id: emitter;
            anchors.centerIn: parent;
            width: 200;
            height: 200;
            system: particleSystem;
            emitRate: 10;
            lifeSpan: 2000;
            lifeSpanVariation: 500;
            size: 16;
            endSize: 32;
        }

        ImageParticle {
            system: particleSystem;
            source: "qrc:/Sources/assets/star.png";
            color: "#FFD700";
            colorVariation: 0.6;
            rotation: 15;
            rotationVariation: 5;
            rotationVelocity: 45;
            rotationVelocityVariation: 15;
            entryEffect: ImageParticle.Scale;
        }
    }

}
  • 我们可以修改粒子进入场景的效果,当粒子生命周期开始时,就会应用这个效果;
  • 使用entryEffect: ImageParticle.Scale添加了一个缩放效果;

七、粒子方向

我们还可以设置粒子轨迹的方向,轨迹取决于一个指定的向量空间,该向量定义了粒子的速度和加速度,以及一个随机的方向。

QML提供了三种不同的向量空间,用于定义粒子的速度和加速度:

  • 点方向(PointDirection):使用x和y值定义的方向;
  • 角度方向(AngleDirection):使用角度定义方向;
  • 目标方向(TargetDirection):使用一个目标点坐标定义方向;

在这里插入图片描述

7.1、PointDirection

PointDirection使用x、y值导出向量空间。例如,你想让粒子轨迹沿着45°角方向,那么就要将x、y值设置成相同的值。

例如:我们希望粒子轨迹从左向右,形成一个15°的角,为了设置粒子轨迹,我们首先需要赋值PointDirection赋值给Emitter的velocity属性;

velocity: PointDirection{};

在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12

import QtQuick.Particles 2.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    Rectangle {
        id: rootItem;
        width: 400;
        height: 400;
        color: "#1f1f1f";

        ParticleSystem {
            id: particleSystem;
        }

        Emitter {
            id: emitter;
            anchors.left: parent.left;
            anchors.verticalCenter: parent.verticalCenter;
            width: 1;
            height: 1;
            system: particleSystem;
            emitRate: 10;
            lifeSpan: 6400;
            lifeSpanVariation: 400;
            size: 32;
            velocity: PointDirection {
                x: 100;
                y: 0;
                xVariation: 0;
                yVariation: 100/6;
            }
        }

        ImageParticle {
            system: particleSystem;
            source: "qrc:/Sources/assets/star.png";
            color: "#FFD700";
            colorVariation: 0.6;
            rotation: 15;
            rotationVariation: 5;
            rotationVelocity: 45;
            rotationVelocityVariation: 15;
            entryEffect: ImageParticle.Scale;
        }
    }

}
  • 设定方向,坐标(100,0),xVariation和yVariation为误差精度;

7.2、AngleDirection

要使用AngleDirection,我们需要将其赋值给Emittervelocity属性:

velocity: AngleDirection{};

粒子发射角度使用angle属性定义,angle属性的取值范围是[0,360],0位水平向右。

我们希望粒子水平向右发射,因此,angle: 0;

粒子速度由magnitude属性决定,magnitude属性单位是像素/秒。如果我们的场景宽度是640px,那么将magnitude属性设置为100的话,这就意味着,粒子平均要消耗6.4秒才能从场景一端移动到另一端。为了让粒子速度更有趣,我们还要设置magnitudeVariation属性,这会为该速度设置一个可变的范围区间;

在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12

import QtQuick.Particles 2.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    Rectangle {
        id: rootItem;
        width: 400;
        height: 400;
        color: "#1f1f1f";

        ParticleSystem {
            id: particleSystem;
        }

        Emitter {
            id: emitter;
            anchors.left: parent.left;
            anchors.verticalCenter: parent.verticalCenter;
            width: 1;
            height: 1;
            system: particleSystem;
            emitRate: 10;
            lifeSpan: 6400;
            lifeSpanVariation: 400;
            size: 32;
            velocity: AngleDirection {
                angle: 0;
                angleVariation: 15;
                magnitude: 100;
                magnitudeVariation: 50;
            }
        }

        ImageParticle {
            system: particleSystem;
            source: "qrc:/Sources/assets/star.png";
            color: "#FFD700";
            colorVariation: 0.6;
            rotation: 15;
            rotationVariation: 5;
            rotationVelocity: 45;
            rotationVelocityVariation: 15;
            entryEffect: ImageParticle.Scale;
        }
    }

}

接下来看加速度,加速度为每一个粒子添加一个加速度向量,该向量会随着时间流逝而改变速度。
例如,我们创建一个类似星轨的轨迹,为了达到这一目的,我们将方向修改为-45°,并且移除速度变量区间:

velocity: AngleDirection {
	angle: -45;
	magnitude: 100;
}

加速度方向为90°向下,数值为25:

acceleration: AngleDirection {
	angle: 90;
	magnitude: 25
}

在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12

import QtQuick.Particles 2.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    Rectangle {
        id: rootItem;
        width: 400;
        height: 400;
        color: "#1f1f1f";

        ParticleSystem {
            id: particleSystem;
        }

        Emitter {
            id: emitter;
            anchors.left: parent.left;
            anchors.verticalCenter: parent.verticalCenter;
            width: 1;
            height: 1;
            system: particleSystem;
            emitRate: 10;
            lifeSpan: 6400;
            lifeSpanVariation: 400;
            size: 32;
            velocity: AngleDirection {
                angle: -45;
                magnitude: 100;
            }
            acceleration: AngleDirection {
                angle: 90;
                magnitude: 25;
            }
        }

        ImageParticle {
            system: particleSystem;
            source: "qrc:/Sources/assets/star.png";
            color: "#FFD700";
            colorVariation: 0.6;
            rotation: 15;
            rotationVariation: 5;
            rotationVelocity: 45;
            rotationVelocityVariation: 15;
            entryEffect: ImageParticle.Scale;
        }
    }

}

7.3、TargetDirection

TargetDirection使用某个项目指定一个目标点,targetItem指定目标位置关联Item,Item的中心会成为目标点

首先我们在界面右侧中心设置一个目标点:

Rectangle {
	id: targetPoint;
	anchors.right: parent.right;
	anchors.verticalCenter: parent.verticalCenter;
	width: 10;
	height: 10;
	radius: 10;
	color: "red";
}

我们将TargetDirection的targetItem属性设置为targetPoint,targetVariation的值为100/6,这大约会形成一个15°的角;

Emitter {
	id: emitter;
    anchors.left: parent.left;
    anchors.verticalCenter: parent.verticalCenter;
    width: 1;
    height: 1;
    system: particleSystem;
    emitRate: 10;
    lifeSpan: 6400;
    lifeSpanVariation: 400;
    size: 32;
    velocity: TargetDirection {
    	targetItem: targetPoint;
        targetVariation: 100/6;
        magnitude: 100;
    }
}

在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12

import QtQuick.Particles 2.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    Rectangle {
        id: rootItem;
        width: 400;
        height: 400;
        color: "#1f1f1f";

        ParticleSystem {
            id: particleSystem;
        }

        Rectangle {
            id: targetPoint;
            anchors.right: parent.right;
            anchors.verticalCenter: parent.verticalCenter;
            width: 10;
            height: 10;
            radius: 10;
            color: "red";
        }

        Emitter {
            id: emitter;
            anchors.left: parent.left;
            anchors.verticalCenter: parent.verticalCenter;
            width: 1;
            height: 1;
            system: particleSystem;
            emitRate: 10;
            lifeSpan: 6400;
            lifeSpanVariation: 400;
            size: 32;
            velocity: TargetDirection {
                targetItem: targetPoint;
                targetVariation: 100/6;
                magnitude: 100;
            }
        }

        ImageParticle {
            system: particleSystem;
            source: "qrc:/Sources/assets/star.png";
            color: "#FFD700";
            colorVariation: 0.6;
            rotation: 15;
            rotationVariation: 5;
            rotationVelocity: 45;
            rotationVelocityVariation: 15;
            entryEffect: ImageParticle.Scale;
        }
    }

}

八、粒子控制

粒子由发射器发射,一旦粒子发射出来,发射器的任务也就完成了,不会再对粒子有任何影响。如果我们需要控制已发射的粒子,需要使用粒子控制器(Affector);

Affector属性介绍:

属性类型描述
accelerationStochasticDirection受影响的粒子将其加速度设置这个方向
enabledbool如果设置为false,此影响器不会影响任何粒子,默认值为true
groupslist<string>哪些逻辑粒子组将受到影响。如果为空,它将影响所有粒子
oncebool如果once被设置为true,这个影响器将只影响每个粒子一次。如果影响器通常模拟一段时间内的连续效应,那么它将模拟一秒时间内的效应即它影响粒子的瞬间。默认为false
positionStochasticDirection受影响的粒子将其位置设置为这个方向,相对于粒子系统。当将方向解释为点时,可以将其想象为一个箭头,其基础在ParticleSystem的0,0处,尖端在指定位置处。
relativebool受影响的粒子是否将其现有的位置/速度/加速度添加到新粒子上。默认值为true。
shapeShape如果已定义大小,则形状属性可用于影响非矩形区域
systemParticleSystem这就是受元件影响的系统。如果Affector是一个粒子系统的直接子元素,它将自动与粒子系统相关联。
velocityStochasticDirection受影响的粒子将其速度设置为这个方向
whenCollidingWithlist<string>如果这里指定了任何逻辑粒子组,那么只有当被选中的粒子与这些组中的一个粒子相交时,才会触发影响器。这与groups属性不同。groups属性选择哪些粒子可以被检查,如果它们满足其他标准(包括在Affector的范围内,通过形状修改),那么它们将再次被测试,以查看它们是否与whenCollidingWith中的一个粒子组中的粒子相交。默认情况下,不指定任何组

Affector影响器有一个基础类型Affector,下面有八个子类型:

控制器说明
Age改变粒子生命周期,一般用于提前结束粒子的生命周期
Attractor将粒子吸引到一个指定的点
Friction按比例降低粒子的当前速率
Gravity添加一个一定角度的加速度
Turbulence为粒子添加一个图像噪音
Wander随机改变粒子轨迹
GroupGoal改变粒子组状态
SpriteGoal改变精灵粒子状态

8.1、Age

Age可以改变粒子生命周期,lifeLeft属性指定粒子还能存活多少时间。

在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12

import QtQuick.Particles 2.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    Rectangle {
        id: rootItem;
        width: 400;
        height: 400;
        color: "#1f1f1f";

        ParticleSystem {
            id: particleSystem;
        }

        Rectangle {
            id: targetPoint;
            anchors.right: parent.right;
            anchors.verticalCenter: parent.verticalCenter;
            width: 10;
            height: 10;
            radius: 10;
            color: "red";
        }

        Emitter {
            id: emitter;
            anchors.left: parent.left;
            anchors.verticalCenter: parent.verticalCenter;
            width: 1;
            height: 1;
            system: particleSystem;
            emitRate: 10;
            lifeSpan: 5000;
            lifeSpanVariation: 400;
            size: 32;
            velocity: TargetDirection {
                targetItem: targetPoint;
                targetVariation: 100/6;
                magnitude: 100;
            }
        }

        ImageParticle {
            system: particleSystem;
            source: "qrc:/Sources/assets/star.png";
            color: "#FFD700";
            colorVariation: 0.6;
            rotation: 15;
            rotationVariation: 5;
            rotationVelocity: 45;
            rotationVelocityVariation: 15;
            entryEffect: ImageParticle.Scale;
        }

        Age {
            anchors.centerIn: parent;
            width: 140;
            height: 120;
            system: particleSystem;
            advancePosition: true;
            lifeLeft: 2500;
            once: true;

            Rectangle {
                anchors.fill: parent;
                color: "transparent";
                border.color: "green";
                border.width: 2;
            }
        }
    }

}
  • 添加的居中绿色矩形区域为Age控制器的区域范围;
  • 发射器设置的粒子生命周期为5000,Age控制器的生命周期为2500,也就是说,当粒子进入Age控制器区域后,生命周期就剩下2500了;
  • advancePosition设置为true,粒子就会从其预期的位置从新出现(参考剩余生命周期、粒子速度和到目标点的距离来推算预期的位置);

8.2、Attractor

Attractor将粒子吸引到pointX和pointY指定的点,strength属性指定吸引的强度;

强度为1.0
在这里插入图片描述


强度为100.0
在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12

import QtQuick.Particles 2.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    Rectangle {
        id: rootItem;
        width: 400;
        height: 400;
        color: "#1f1f1f";

        ParticleSystem {
            id: particleSystem;
        }

        Rectangle {
            id: targetPoint;
            anchors.right: parent.right;
            anchors.verticalCenter: parent.verticalCenter;
            width: 10;
            height: 10;
            radius: 10;
            color: "red";
        }

        Emitter {
            id: emitter;
            anchors.left: parent.left;
            anchors.verticalCenter: parent.verticalCenter;
            width: 1;
            height: 1;
            system: particleSystem;
            emitRate: 10;
            lifeSpan: 10000;
            lifeSpanVariation: 400;
            size: 32;
            velocity: TargetDirection {
                targetItem: targetPoint;
                targetVariation: 100/6;
                magnitude: 100;
            }
        }

        ImageParticle {
            system: particleSystem;
            source: "qrc:/Sources/assets/star.png";
            color: "#FFD700";
            colorVariation: 0.6;
            rotation: 15;
            rotationVariation: 5;
            rotationVelocity: 45;
            rotationVelocityVariation: 15;
            entryEffect: ImageParticle.Scale;
        }

        Attractor {
            anchors.centerIn: parent;
            width: 160;
            height: 70;
            system: particleSystem;
            pointX: 0;
            pointY: 0;
            strength: 100.0

            Rectangle {
                anchors.fill: parent;
                color: "transparent";
                border.color: "green";
                border.width: 2;
            }
        }
    }

}
  • 我们的控制器位于界面中间,当粒子进入控制器范围时,控制器会影响粒子向(0,0)点方向移动;

8.3、Friction

Friction会按一定比例降低粒子速度

在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12

import QtQuick.Particles 2.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    Rectangle {
        id: rootItem;
        width: 400;
        height: 400;
        color: "#1f1f1f";

        ParticleSystem {
            id: particleSystem;
        }

        Rectangle {
            id: targetPoint;
            anchors.right: parent.right;
            anchors.verticalCenter: parent.verticalCenter;
            width: 10;
            height: 10;
            radius: 10;
            color: "red";
        }

        Emitter {
            id: emitter;
            anchors.left: parent.left;
            anchors.verticalCenter: parent.verticalCenter;
            width: 1;
            height: 1;
            system: particleSystem;
            emitRate: 10;
            lifeSpan: 10000;
            lifeSpanVariation: 400;
            size: 32;
            velocity: TargetDirection {
                targetItem: targetPoint;
                targetVariation: 100/6;
                magnitude: 100;
            }
        }

        ImageParticle {
            system: particleSystem;
            source: "qrc:/Sources/assets/star.png";
            color: "#FFD700";
            colorVariation: 0.6;
            rotation: 15;
            rotationVariation: 5;
            rotationVelocity: 45;
            rotationVelocityVariation: 15;
            entryEffect: ImageParticle.Scale;
        }

        Friction {
            anchors.centerIn: parent;
            width: 160;
            height: 70;
            system: particleSystem;
            factor: 0.8;
            threshold: 25;

            Rectangle {
                anchors.fill: parent;
                color: "transparent";
                border.color: "green";
                border.width: 2;
            }
        }
    }

}
  • 粒子进入控制器范围后,会以factor系数为0.8的比例降低粒子速度,直到降低到threshold: 25px/s;

8.4、Gravity

Gravity位粒子添加一个加速度;
在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12

import QtQuick.Particles 2.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    Rectangle {
        id: rootItem;
        width: 400;
        height: 400;
        color: "#1f1f1f";

        ParticleSystem {
            id: particleSystem;
        }

        Rectangle {
            id: targetPoint;
            anchors.right: parent.right;
            anchors.verticalCenter: parent.verticalCenter;
            width: 10;
            height: 10;
            radius: 10;
            color: "red";
        }

        Emitter {
            id: emitter;
            anchors.left: parent.left;
            anchors.verticalCenter: parent.verticalCenter;
            width: 1;
            height: 1;
            system: particleSystem;
            emitRate: 10;
            lifeSpan: 10000;
            lifeSpanVariation: 400;
            size: 32;
            velocity: TargetDirection {
                targetItem: targetPoint;
                targetVariation: 100/6;
                magnitude: 100;
            }
        }

        ImageParticle {
            system: particleSystem;
            source: "qrc:/Sources/assets/star.png";
            color: "#FFD700";
            colorVariation: 0.6;
            rotation: 15;
            rotationVariation: 5;
            rotationVelocity: 45;
            rotationVelocityVariation: 15;
            entryEffect: ImageParticle.Scale;
        }

        Gravity {
            anchors.centerIn: parent;
            width: 160;
            height: 70;
            system: particleSystem;
            magnitude: 50;
            angle: 90;

            Rectangle {
                anchors.fill: parent;
                color: "transparent";
                border.color: "green";
                border.width: 2;
            }
        }
    }

}
  • 进入控制器范围的粒子都会被添加一个大小为50,方向为向下90°的加速度;

8.5、Turbulence

Turbulence为粒子添加一个力向量,每个粒子获得的力向量都是随机的,这是由一个噪音图像决定的,使用noiseSource可以自定义噪音图像,strength定义了力向量强度;

在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12

import QtQuick.Particles 2.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    Rectangle {
        id: rootItem;
        width: 400;
        height: 400;
        color: "#1f1f1f";

        ParticleSystem {
            id: particleSystem;
        }

        Rectangle {
            id: targetPoint;
            anchors.right: parent.right;
            anchors.verticalCenter: parent.verticalCenter;
            width: 10;
            height: 10;
            radius: 10;
            color: "red";
        }

        Emitter {
            id: emitter;
            anchors.left: parent.left;
            anchors.verticalCenter: parent.verticalCenter;
            width: 1;
            height: 1;
            system: particleSystem;
            emitRate: 10;
            lifeSpan: 10000;
            lifeSpanVariation: 400;
            size: 32;
            velocity: TargetDirection {
                targetItem: targetPoint;
                targetVariation: 100/6;
                magnitude: 100;
            }
        }

        ImageParticle {
            system: particleSystem;
            source: "qrc:/Sources/assets/star.png";
            color: "#FFD700";
            colorVariation: 0.6;
            rotation: 15;
            rotationVariation: 5;
            rotationVelocity: 45;
            rotationVelocityVariation: 15;
            entryEffect: ImageParticle.Scale;
        }

        Turbulence {
            anchors.centerIn: parent;
            width: 160;
            height: 70;
            system: particleSystem;
            strength: 100;

            Rectangle {
                anchors.fill: parent;
                color: "transparent";
                border.color: "green";
                border.width: 2;
            }
        }
    }

}
  • 粒子一旦进入控制器范围,就会发疯一样乱窜,而不是安装从左到右的方向保持一个大致轨迹;

8.6、Wander

Wander控制轨迹,affectedParameter属性指定控制哪一属性(速度/位置/加速度),pace属性指定每秒该属性变化的最大值,xVariance和yVariance指定粒子轨迹x和y坐标的浮动区间。

在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12

import QtQuick.Particles 2.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    Rectangle {
        id: rootItem;
        width: 400;
        height: 400;
        color: "#1f1f1f";

        ParticleSystem {
            id: particleSystem;
        }

        Rectangle {
            id: targetPoint;
            anchors.right: parent.right;
            anchors.verticalCenter: parent.verticalCenter;
            width: 10;
            height: 10;
            radius: 10;
            color: "red";
        }

        Emitter {
            id: emitter;
            anchors.left: parent.left;
            anchors.verticalCenter: parent.verticalCenter;
            width: 1;
            height: 1;
            system: particleSystem;
            emitRate: 10;
            lifeSpan: 10000;
            lifeSpanVariation: 400;
            size: 32;
            velocity: TargetDirection {
                targetItem: targetPoint;
                targetVariation: 100/6;
                magnitude: 100;
            }
        }

        ImageParticle {
            system: particleSystem;
            source: "qrc:/Sources/assets/star.png";
            color: "#FFD700";
            colorVariation: 0.6;
            rotation: 15;
            rotationVariation: 5;
            rotationVelocity: 45;
            rotationVelocityVariation: 15;
            entryEffect: ImageParticle.Scale;
        }

        Wander {
            anchors.centerIn: parent;
            width: 160;
            height: 70;
            system: particleSystem;
            affectedParameter: Wander.Position;
            pace: 200;
            yVariance: 240;

            Rectangle {
                anchors.fill: parent;
                color: "transparent";
                border.color: "green";
                border.width: 2;
            }
        }
    }

}
  • 控制器作用于粒子轨迹的位置属性,轨迹以每秒200次的频率在y轴方向上随机振动;

8.7、GroupGoal


8.8、SpriteGoal


九、粒子组-ParticleGroup

每一个粒子都是粒子组(ParticleGroup)的成员,通过其name属性区分,当没有指定粒子所属的粒子组时,这些粒子默认也都在一个粒子组,不过name属性值是个空字符串,粒子组主要是为了方便控制粒子行为状态;

在这里插入图片描述

import QtQuick 2.12
import QtQuick.Window 2.12

import QtQuick.Particles 2.0

Window {
    id: root;
    width: 400;
    height: 400;
    visible: true;

    Rectangle {
        id: rootItem;
        width: 400;
        height: 400;
        color: "#1f1f1f";

        ParticleSystem {
            id: particleSystem;
        }

        Rectangle {
            id: targetPoint;
            anchors.right: parent.right;
            anchors.verticalCenter: parent.verticalCenter;
            width: 10;
            height: 10;
            radius: 10;
            color: "red";
        }

        Emitter {
            id: emitter;
            anchors.left: parent.left;
            anchors.verticalCenter: parent.verticalCenter;
            group: "A";
            width: 1;
            height: 1;
            system: particleSystem;
            emitRate: 10;
            lifeSpan: 6400;
            lifeSpanVariation: 400;
            size: 32;
            velocity: TargetDirection {
                targetItem: targetPoint;
                targetVariation: 100/6;
                magnitude: 100;
            }
        }

        Emitter {
            id: emitter2;
            anchors.left: parent.left;
            anchors.bottom: parent.bottom;
            anchors.bottomMargin: 20;
            group: "B";
            width: 10;
            height: 10;
            system: particleSystem;
            emitRate: 10;
            lifeSpan: 6400;
            lifeSpanVariation: 400;
            size: 10;
            velocity: AngleDirection {
                angle: 0;
                magnitude: 100;
            }
        }

        ImageParticle {
            system: particleSystem;
            groups: "A";
            source: "qrc:/Sources/assets/star.png";
            color: "#FFD700";
            colorVariation: 0.6;
            rotation: 15;
            rotationVariation: 5;
            rotationVelocity: 45;
            rotationVelocityVariation: 15;
            entryEffect: ImageParticle.Scale;
        }

        ItemParticle {
            system: particleSystem;
            groups: "B";
            delegate: Rectangle {
                color: "green";
                width: 10;
                height: 10;
                radius: 10;
            }
        }

        Wander  {
            anchors.centerIn: parent;
            width: 160;
            height: parent.height;
            system: particleSystem;
            groups: ["A","B"];
            affectedParameter: Wander.Position;
            pace: 500;
            yVariance: 400;

            Rectangle {
                anchors.fill: parent;
                color: "transparent";
                border.color: "green";
                border.width: 2;
            }
        }
    }

}
  • 定义了两个粒子发射器,分别是groupA和groupB;
  • groupA使用的是ImageParticle画刷,groupB使用的是ItemParticle画刷;
  • 两个组同时使用Wander控制器;

十、烟花案例

转载自:【使用Qt Quick Particle System粒子系统实现烟花效果】https://blog.csdn.net/yafeilinux/article/details/86530616

在这里插入图片描述

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Particles 2.12
import QtMultimedia 5.9

Window {
    visible: true;
    width: 800;
    height: 530;
    color: "black";
    title: qsTr("Hello World");

    //声音
    SoundEffect {
        id:playSound;
        source: "qrc:/sound.wav";
    }

    //背景
    Image {
        anchors.fill: parent;
        source: "qrc:/back.jpg";
    }

    //粒子系统
    ParticleSystem {
        id: particles;
        anchors.fill: parent;

        //-----------------------------------------------------------------
        //发射出去的粒子画笔
        ImageParticle {
            groups: ["stage1"];                             //分组为stage1
            source: "qrc:///particleresources/star.png";    //这是QML内置的一个路径,能够在源代码包内搜索particlesources这个目录
            alphaVariation: 0.4;                            //透明度误差
            colorVariation: 0.9;                            //颜色误差
        }

        //发射出去的粒子发射器
        Emitter {
            id: burstEmitter;
            x: 400;
            y: 480;
            group: "stage1";    //分组为stage1
            emitRate: 3;        //发射速率为1秒5个
            lifeSpan: 1500;     //粒子生命周期为1500ms
            size: 50;           //粒子大小为50px
            endSize: 10;        //粒子消亡时大小为10px
            sizeVariation: 30;  //粒子大小误差
            acceleration: PointDirection {  //粒子加速度
                y: 100;
            }
            velocity: AngleDirection {      //粒子速率
                angle: 270;             //粒子发射角度
                magnitude: 400;         //粒子速率为400像素/秒
                angleVariation: 40;     //角度误差
                magnitudeVariation: 50; //速率误差
            }
        }
        //-----------------------------------------------------------------

        //-----------------------------------------------------------------
        //发射出去的粒子后面烟气效果粒子画笔
        ImageParticle {
            groups: ["stage2"];                                 //分组为stage2
            source: "qrc:///particleresources/glowdot.png";     //这是QML内置的一个路径,能够在源代码包内搜索particlesources这个目录
            color: "#11111111";                                 //粒子颜色
        }

        //发射出去的粒子后面烟气效果粒子发射器
        TrailEmitter {
            group: "stage2";    //分组为stage2
            follow: "stage1";   //跟随stage1
            emitRatePerParticle: 100;
            lifeSpan: 2400;             //粒子生命周期为2400ms
            lifeSpanVariation: 400;     //粒子生命周期误差
            size: 16;                   //粒子大小
            endSize: 0;                 //粒子生命周期结束时大小
            sizeVariation: 8;           //粒子大小误差
            acceleration: PointDirection {  //粒子加速度
                y: -60;
            }
            velocity: AngleDirection {      //粒子速率
                angle: 270;             //粒子发射角度
                magnitude: 40;          //粒子速率为40像素/秒
                angleVariation: 22;     //角度误差
                magnitudeVariation: 5;  //速率误差
            }
        }
        //-----------------------------------------------------------------

        //-----------------------------------------------------------------
        //爆炸的粒子画笔
        ImageParticle {
            id: imageParticle;
            groups: ["stage3"];                             //分组为stage3
            source: "qrc:///particleresources/star.png";    //这是QML内置的一个路径,能够在源代码包内搜索particlesources这个目录
            alpha: 0;
            colorVariation: 0.2;                //颜色误差
            entryEffect: ImageParticle.Scale;   //粒子效果为放缩
            rotation: 60;                       //旋转角度
            rotationVariation: 30;              //旋转角度误差
            rotationVelocity: 45;               //旋转速率
            rotationVelocityVariation: 15;      //旋转速率误差
        }

        //爆炸的粒子发射器
        Emitter {
            id: burstEmitter2;
            group: "stage3";    //分组为stage3
            emitRate: 4000;     //发射速率为4000个每秒
            lifeSpan: 3000;     //生命周期为3000ms
            size: 30;           //粒子大小
            endSize: 5;         //粒子生命周期结束时大小
            sizeVariation:10;   //粒子大小误差
            enabled: false;     //发射器不起作用
            velocity: CumulativeDirection {     //粒子速率,CumulativeDirection将多个方向合一
                AngleDirection {
                    angleVariation: 360;
                    magnitudeVariation: 80;
                }
                PointDirection {
                    y: 20;
                }
            }
            acceleration: PointDirection {      //粒子加速度
                y: 10;
            }
        }
        //-----------------------------------------------------------------

        //-----------------------------------------------------------------
        //粒子控制器
        Affector {
            system: particles
            width: parent.width
            height: 10;
            y: 90;
            once: true;             //只影响粒子一次
            groups: "stage1";       //影响分组stage1的粒子
            onAffectParticles: {
                for (var i=0; i<particles.length; i++) {
                    burstEmitter2.burst(500, particles[i].x, particles[i].y);   //Emitter::burst(int count, int x, int y)会在(x,y)出瞬间发射出count个粒子
                    imageParticle.color = Qt.rgba(particles[i].red, //设置爆炸粒子画笔的颜色
                                                particles[i].green,
                                                particles[i].blue,
                                                particles[i].alpha)
                    playSound.play();   //播放声音
                }
            }

//            Rectangle {
//                anchors.fill: parent;
//                color: "transparent";
//                border.color: "green";
//                border.width: 2;
//            }
        }
    }
}

  • 5
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贝勒里恩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值