此系列的所有文章都可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873

前段时间去听了Qt在北京的开发人员大会,感觉QML是大势所趋。所以回来后想好好补补QML方面的东西。无奈不管是书籍还是网络上,这方面的教材都太少了。

霍亚飞的《Qt Creator高速入门》第二版中做了一些介绍。但也仅仅是主要的元素,布局,动画等。QML绚丽的粒子特效。传感器,多媒体模块,WebView。GPS。蓝牙等等...都没有提及。

所以这段时间也在做Qt官网QML Applications这个教材的翻译,大家有兴趣的也能够看看。

好了,废话不多说,我们今天就来看一个 Qt 粒子系列中的第一个样例Emitters:

我们还是先看看介绍怎么说:

This is a collection of small QML examples relating to using Emitters in the particle system.

Each example is a small QML file emphasizing a particular type or feature.

也就是说,这个样例是由非常多使用Emitters的小样例构成的,每一个小样例突出了Emitter的一个特性。我们一个个来看~

首先,我们要知道Emitter是QML粒子系统中的“发射器”。能够理解为每一个粒子都是通过这个“发射器”“发射”到屏幕上去的。在这个发射器中,我们就能够设置一些粒子显示的基本属性了。比如发射多少个粒子,每一个粒子生命周期多长,发射到哪个坐标点上,等等等等。这样。只通过操作发射器,我们就能够实现一个主要的粒子显示效果,这也是这个demo的由来。

首先我们执行该demo,出现的是一个选择页面,每一个页面进去都一个Emitter的小样例:

这个页面的代码实现就不提了,我们以它内容中的顺序来:

在这个demo中qml文件以资源文件的形式存放,我们在资源中找到emitters.qrc。里面的velocityfrommotion.qml就是代表了我们第一个内容的qml文件。

(1)Velocity from Motion

从这个标题我们能够知道。它演示了怎样使用Emitter来控制粒子的运动速率。

我们先看其执行效果再来看代码:

我们能够看到有一圈粒子以中心点为圆心在做半径可变的圆周运动。还有一部分粒子则做螺旋式圆周运动。

假设在屏幕上点击鼠标并拖动,粒子还会产生在鼠标所在位置(假设是触屏则是触碰位置),效果十分好看。

velocityfrommotion.qml:

import QtQuick 2.0
import QtQuick.Particles 2.0 Rectangle { // 矩形根元素 id: root height: 540
width: 360 gradient: Gradient { // 增加渐变效果
GradientStop { position: 0; color: "#000020" }
GradientStop { position: 1; color: "#000000" }
} MouseArea { // 为了实现点击效果增加
id: mouseArea
anchors.fill: root
} ParticleSystem { id: sys1 } // 基于ParticleSystem的粒子特效
ImageParticle { // 也是粒子系统的基本元素
system: sys1 // 指明系统
source: "qrc:///particleresources/glowdot.png" // 这里选用了“光点”粒子。详细内容见下方第(1)点
color: "cyan" // 颜色
alpha: 0 // 透明度
SequentialAnimation on color { // 在颜色上增加动画
loops: Animation.Infinite // 无限循环。等同-1,假设是正值则循环详细次数
ColorAnimation { // 颜色动画
from: "cyan"
to: "magenta"
duration: 1000
}
ColorAnimation {
from: "magenta"
to: "blue"
duration: 2000
}
ColorAnimation {
from: "blue"
to: "violet"
duration: 2000
}
ColorAnimation {
from: "violet"
to: "cyan"
duration: 2000
}
}
colorVariation: 0.3 // 颜色变化率。从0到1,越大粒子群的色彩越丰富
}
//! [0]
Emitter { // 这就是我们的发射器了
id: trailsNormal
system: sys1 // 一样要指明详细的粒子系统 emitRate: 500 // 每秒粒子发射数
lifeSpan: 2000 // 粒子生命周期(毫秒) y: mouseArea.pressed ? mouseArea.mouseY : circle.cy // 发射到的坐标值
x: mouseArea.pressed ? mouseArea.mouseX : circle.cx // 这里使用mouseArea检測是否按下。有则使用按下的坐标,否则使用以下的计算坐标。 这里的粒子之所以能够持续的发射,其缘由正是QML的属性绑定,由于这个坐标值的持续变化。造成了我们所见的粒子动画。 velocity: PointDirection {xVariation: 4; yVariation: 4;} // 当粒子产生后。其扩散行为在x,y方向上的速度
acceleration: PointDirection {xVariation: 10; yVariation: 10;} // 扩散行为的加速度
velocityFromMovement: 8 // 基于当前粒子的运动为其增加一个额外的速度向量 size: 8 // 粒子大小,单位是像素,默觉得16
sizeVariation: 4 // 一个会随机加到size和endSize上的增量
}
//! [0]
ParticleSystem { id: sys2 } // 第二个粒子系统,与前者大同小异
ImageParticle {
color: "cyan"
system: sys2
alpha: 0
SequentialAnimation on color {
loops: Animation.Infinite
ColorAnimation {
from: "magenta"
to: "cyan"
duration: 1000
}
ColorAnimation {
from: "cyan"
to: "magenta"
duration: 2000
}
}
colorVariation: 0.5
source: "qrc:///particleresources/star.png" // 这里选取了一种不同的粒子。star更小更亮且具有两条发亮的对角线
}
Emitter {
id: trailsStars
system: sys2 emitRate: 100 // 较少的星星掺杂在光点中,达到绚丽的效果
lifeSpan: 2200 y: mouseArea.pressed ? mouseArea.mouseY : circle.cy
x: mouseArea.pressed ? mouseArea.mouseX : circle.cx velocity: PointDirection {xVariation: 4; yVariation: 4;}
acceleration: PointDirection {xVariation: 10; yVariation: 10;}
velocityFromMovement: 8 size: 22
sizeVariation: 4
}
ParticleSystem { id: sys3; } // 螺旋运动的粒子
ImageParticle {
source: "qrc:///particleresources/glowdot.png"
system: sys3
color: "orange"
alpha: 0
SequentialAnimation on color { // 初始值为橙色。但颜色动画仅需在红绿间切换,由于橙色是其过渡色
loops: Animation.Infinite
ColorAnimation {
from: "red"
to: "green"
duration: 2000
}
ColorAnimation {
from: "green"
to: "red"
duration: 2000
}
} colorVariation: 0.2 // 假设这个值是1,就看不出上述的动画效果了,假设为0,粒子群的颜色显得单调 }
Emitter {
id: trailsNormal2
system: sys3 emitRate: 300
lifeSpan: 2000 y: mouseArea.pressed ? mouseArea.mouseY : circle2.cy
x: mouseArea.pressed ? mouseArea.mouseX : circle2.cx velocityFromMovement: 16 velocity: PointDirection {xVariation: 4; yVariation: 4;}
acceleration: PointDirection {xVariation: 10; yVariation: 10;} size: 12
sizeVariation: 4
}
ParticleSystem { id: sys4; }
ImageParticle {
system: sys4
source: "qrc:///particleresources/star.png"
color: "green"
alpha: 0
SequentialAnimation on color {
loops: Animation.Infinite
ColorAnimation {
from: "green"
to: "red"
duration: 2000
}
ColorAnimation {
from: "red"
to: "green"
duration: 2000
}
} colorVariation: 0.5
}
Emitter {
id: trailsStars2
system: sys4 emitRate: 50
lifeSpan: 2200 y: mouseArea.pressed ? mouseArea.mouseY : circle2.cy
x: mouseArea.pressed ? mouseArea.mouseX : circle2.cx velocityFromMovement: 16
velocity: PointDirection {xVariation: 2; yVariation: 2;}
acceleration: PointDirection {xVariation: 10; yVariation: 10;} size: 22
sizeVariation: 4
} color: "white" // 不明确这个color的意义,由于矩形的颜色在渐变那里已经被确定了 Item { // 我们能够使用Item来包括一个逻辑对象,并为它命名。定义其属性来进行调用
id: circle
//anchors.fill: parent
property real radius: 0 // 定义属性radius
property real dx: root.width / 2 // 圆心横坐标dx
property real dy: root.height / 2 // 圆心纵坐标dy
property real cx: radius * Math.sin(percent*6.283185307179) + dx // 计算当前横坐标cx
property real cy: radius * Math.cos(percent*6.283185307179) + dy // 计算当前纵坐标cy
property real percent: 0 // 百分比percent SequentialAnimation on percent { // 使用连续动画改变<span style="font-family: Arial, Helvetica, sans-serif;">自己定义属性percent</span> loops: Animation.Infinite
running: true
NumberAnimation { // 数值动画,注意到这里的往复动画会使粒子顺时针、逆时针交替运动。实际效果也是如此
duration: 1000
from: 1
to: 0
loops: 8
}
NumberAnimation {
duration: 1000
from: 0
to: 1
loops: 8
} } SequentialAnimation on radius { // 半径的动画
loops: Animation.Infinite
running: true
NumberAnimation {
duration: 4000
from: 0
to: 100
}
NumberAnimation {
duration: 4000
from: 100
to: 0
}
}
} Item { // 外圈螺旋式运动的粒子须要两个逻辑对象控制其公转与自转
id: circle3
property real radius: 100
property real dx: root.width / 2
property real dy: root.height / 2
property real cx: radius * Math.sin(percent*6.283185307179) + dx
property real cy: radius * Math.cos(percent*6.283185307179) + dy
property real percent: 0 SequentialAnimation on percent { // 这里的百分比仅使用一个循环,就不会产生顺逆时针的交替运动
loops: Animation.Infinite
running: true
NumberAnimation { from: 0.0; to: 1 ; duration: 10000; }
}
} Item {
id: circle2
property real radius: 30
property real dx: circle3.cx // 注意这里的圆心就不再是屏幕圆心了
property real dy: circle3.cy
property real cx: radius * Math.sin(percent*6.283185307179) + dx
property real cy: radius * Math.cos(percent*6.283185307179) + dy
property real percent: 0 SequentialAnimation on percent {
loops: Animation.Infinite
running: true
NumberAnimation { from: 0.0; to: 1 ; duration: 1000; }
}
} }

第一点:要注意这一句source: "qrc:///particleresources/glowdot.png"并非从资源文件里取来的glowdot.png这个文件,类似QML中绝对路径的file:///...一样,这是其内置的一个路径。查看ImageParticle的帮助文档我们能够知道。Qt提供了3种默认的粒子图片,且都是白色以及像素级的,这是为了使渲染和透明度达到更好的效果。这三个图片的路径各自是qrc:///particleresources/star.png、qrc:///particleresources/glowdot.png、qrc:///particleresources/fuzzydot.png。

实际而言。假设你下载了Qt
源代码包,应该是另一个内置图片的,名为noise.png,路径为qrc:///particleresources/noise.png(这里的源代码版本号是Qt 5.2.0)。

你能够在源代码包内搜索particlesources这个目录。其内容例如以下:

(2)Burst and Pulse



第一节的代码挺多的,后面的都略微要少一些。第二个内容从标题能够得知其使用粒子构建了爆炸和脉冲效果。

先看看显示效果:

这些粒子会以这两个文字为中心交替四散开来。

burstandpulse.qml:

import QtQuick 2.0
import QtQuick.Particles 2.0 Rectangle { // 还是矩形背景,只是定义了一个属性用来进行逻辑推断
width: 320
height: 480
color: "black"
property bool lastWasPulse: false
Timer {
interval: 3500 // 3.5秒定时器
triggeredOnStart: true
running: true
repeat: true
onTriggered: {
//! [0]
if (lastWasPulse) { // 假设上次是脉冲
burstEmitter.burst(500); // burstEmitter调用burst发射500个粒子(一次)
lastWasPulse = false;
} else {
pulseEmitter.pulse(500); // 这里的pulse(500)会先检查pulseEmitter是否在执行。假设没有则会将它激活500毫秒。然后停止。所以尽管pulseEmitter和burstEmitter的代码一模一样,但粒子效果不同,因为Emitter每秒发射1000个粒子。0.5秒也是500个。但它是在一个持续时间内发射的,因此粒子带相对burstEmitter更宽。
lastWasPulse = true;
}
//! [0]
}
}
ParticleSystem { // 这里将ParticleSystem作为ImageParticle、Emitter的父对象。它们就不再须要指定系统
id: particles
anchors.fill: parent
ImageParticle { // 基本图像粒子
source: "qrc:///particleresources/star.png"
alpha: 0
colorVariation: 0.6 // 0.6保证了丰富的色彩
} Emitter { // 与上面的样例不同,这个粒子系统包括两个发射器
id: burstEmitter
x: parent.width/2 // 最基本的是。这里的Emitter没有了属性绑定,因此须要在定时器中手动调用burst和pulse
y: parent.height/3
emitRate: 1000
lifeSpan: 2000
enabled: false
velocity: AngleDirection{magnitude: 64; angleVariation: 360} // 这里使用了AngleDirection以使用角度定义粒子行为。magnitude指明了在该角度的每秒运动距离(像素),angleVariation使粒子方向随机从0到其大小之间产生。 这里也就是一个圆
size: 24
sizeVariation: 8
Text {
anchors.centerIn: parent
color: "white"
font.pixelSize: 18
text: "Burst"
}
}
Emitter {
id: pulseEmitter
x: parent.width/2
y: 2*parent.height/3
emitRate: 1000
lifeSpan: 2000
enabled: false
velocity: AngleDirection{magnitude: 64; angleVariation: 360}
size: 24
sizeVariation: 8
Text {
anchors.centerIn: parent
color: "white"
font.pixelSize: 18
text: "Pulse"
}
}
}
}

(3)Custom Emitter

在这一节中我们将了解到怎样基于Emitter定义更复杂的粒子行为。

执行效果相当华丽:

动态效果更棒。ok,直接上代码:

import QtQuick 2.0
import QtQuick.Particles 2.0 ParticleSystem { // 我们能够直接将ParticleSystem作为根项目
id: sys
width: 360
height: 600
running: true
Rectangle { // 进一步将背景Rectangle作为第一个子项目
z: -1 // 这里z: -1不写也行,只是对于背景元素这样写是好习惯
anchors.fill: parent
color: "black"
} property real petalLength: 180 // 定义了花瓣长度和花瓣旋转属性
property real petalRotation: 0
NumberAnimation on petalRotation {
from: 0;
to: 360;
loops: -1; // 等同于loops: Animation.infinite
running: true
duration: 24000
} function convert(a) {return a*(Math.PI/180);} // JavaScript函数,角度转弧度
Emitter {
lifeSpan: 4000
emitRate: 120
size: 12
anchors.centerIn: parent
//! [0]
onEmitParticles: { // 从名字能够看出,这是一个信号处理函数。相似信号槽机制中的槽函数,它将在粒子被发出时触发。我们能够在这个函数中使用一个JavaScript数组存放我们的粒子群,并以此改变这些粒子的属性,完毕复杂的显示效果。可是运行JavaScript计算的效率是比較慢的,所以在包括大量粒子的系统中不建议这样使用。
for (var i=0; i<particles.length; i++) { // 第二点
var particle = particles[i];
particle.startSize = Math.max(02,Math.min(492,Math.tan(particle.t/2)*24));
var theta = Math.floor(Math.random() * 6.0);
particle.red = theta == 0 || theta == 1 || theta == 2 ? 0.2 : 1;
particle.green = theta == 2 || theta == 3 || theta == 4 ? 0.2 : 1;
particle.blue = theta == 4 || theta == 5 || theta == 0 ? 0.2 : 1;
theta /= 6.0;
theta *= 2.0*Math.PI;
theta += sys.convert(sys.petalRotation);//Convert from degrees to radians
particle.initialVX = petalLength * Math.cos(theta);
particle.initialVY = petalLength * Math.sin(theta);
particle.initialAX = particle.initialVX * -0.5;
particle.initialAY = particle.initialVY * -0.5;
}
}
//! [0]
} ImageParticle {
source: "qrc:///particleresources/fuzzydot.png"
alpha: 0.0
}
}

第二点:我们慢慢剖析这段JavaScript代码:首先使用for针对每一个粒子进行操作,要注意这里取到的粒子是全部生命周期内的粒子。

然后通过 patircle.t 取到粒子从产生到如今的时间,单位秒。

注意这个时间不是针对单个粒子,而是整个粒子系统的。

02限定了粒子的最小初始尺寸。492限制了其最大的初始尺寸。通过这个算式,我们得到了一个从2到492的循环数,可是因为tan 的存在。这个数值在越大的时候会添加得越快。

接着我们产生了一个0-6的随机数,接下来对通过这个随机数设置粒子的RGB值。当theta == 0时。r=0.2,g=1,b=0.2,实际也就是"#51FF51"。

theta == 1时,为“#51FFFF”,其他类似,这样我们使用三个式子得到了6种色彩。

然后theta /= 6.0又一次得到了一个0-1的随机数,然后乘以2π得到一个弧度值,并加上粒子系统当前的旋转角度(之前定义的属性)。

接着我们由此又赋予了粒子对应的初始速度与初始加速度,能够看到。初始加速度与速度成反比。自此,我们的“粒子花瓣”就构成了。

最后不能忘了我们的基本元素ImageParticle,这里採用了fuzzydot元素,大家能够换成star或是glowdot,看看这几个元素显示效果的差别。





(4)Emit Mask

这个小样例展示了QML将图像粒子化的功能。除了粒子化,其粒子的消逝和产生还带来了一种流动的视觉体验。

显示效果例如以下:

其代码只是短短30行。

emitmask.qml:

import QtQuick 2.0
import QtQuick.Particles 2.0 Rectangle {
color: "goldenrod" // 一种比較浓郁的黄色
width: 400
height: 400
ParticleSystem {
width: 300 // 我们相同能够设置粒子系统的尺寸
height: 300
anchors.centerIn: parent ImageParticle {
source: "qrc:///particleresources/glowdot.png" // 假设使用star,更有一种流水的波光凌凌的感觉
z: 2 // z属性继承自item,相同为了保证粒子不被覆盖。 这里能够不写
anchors.fill: parent
color: "#336666CC" // 定义了一个ARGB的颜色值,33为透明度,00-FF透明度逐渐减少。这样不用再额外设置alpha
colorVariation: 0.0 // 保证粒子色彩一致
} Emitter {
anchors.fill: parent
emitRate: 6000
lifeSpan: 720
size: 10
//! [0]
shape: MaskShape { // shape属性能够定义为直线,椭圆以及这里的MaskShape,这样Emitter会将粒子随机发射到规定的形状区域内
source: "../../images/starfish_mask.png" // 这里我们能够使用自己的图片,使用绝对路径或是相对路径
}
//! [0]
} }
}

(5)Maximum Emitted

这个样例展示了在Emitter中限制粒子数量的方法。

通过点击屏幕产生一组发散的粒子:

maximumEmitted.qml:

import QtQuick 2.0
import QtQuick.Particles 2.0 Rectangle {
color: "black"
width: 360
height: 540
ParticleSystem {
id: sys
anchors.fill: parent
onEmptyChanged: if (empty) sys.pause(); // empty是ParticleSystem的一个属性,当该系统中没有“活着”的粒子时,这个值为true。显而易见,onEmptyChanged则是该属性所绑定的一个槽函数(QML 中叫Handler,处理者)。当没有粒子显示时。我们将该系统暂停以节省资源。
ImageParticle {
system: sys
id: cp
source: "qrc:///particleresources/glowdot.png"
colorVariation: 0.4
color: "#000000FF" // 这里将粒子设置为全透明的蓝色,但因为上的的0.4。因此粒子群并非全蓝的
} Emitter {
//burst on click
id: bursty
system: sys // 因为这里的Emitter被ParticleSystem包括,这句并非必须的
enabled: ma.pressed // 将enabled与pressed信号绑定,当按键或手指抬起Emitter即停止
x: ma.mouseX
y: ma.mouseY
emitRate: 16000
maximumEmitted: 4000 // 最大的粒子数为4000个,假设屏蔽这句话,按住鼠标不松开,粒子会被持续发射。而不是如今这样一圈接一圈
acceleration: AngleDirection {angleVariation: 360; magnitude: 360; } // 360度方向,距离360
size: 8
endSize: 16
sizeVariation: 4
} MouseArea {
anchors.fill: parent
onPressed: sys.resume()
id: ma
}
}
}

(6)Shape and Direction

这个样例通过控制粒子的形状和方向创建了一个入口效果。四周的粒子向中心涌入。变小并消逝掉。

shapeanddirection.qml:

import QtQuick 2.0
import QtQuick.Particles 2.0 Rectangle {
id: root
width: 360
height: 540
color: "black"
Image {
anchors.fill: parent
source: "../../images/portal_bg.png" // 这是一张星空的背景图
} ParticleSystem {
id: particles
anchors.fill: parent ImageParticle {
groups: ["center","edge"] // 这个属性继承自ImageParticle的父类ParticlePainter,不同的Emitter可以使用不同的组成员
anchors.fill: parent
source: "qrc:///particleresources/glowdot.png"
colorVariation: 0.1
color: "#009999FF"
} Emitter {
anchors.fill: parent
group: "center" // 选择一个组成员进行发射。默认值为"",这与ImageParticle的groups 的默认值同样。
emitRate: 400
lifeSpan: 2000
size: 20
sizeVariation: 2
endSize: 0 // 设置粒子的结束大小为0,这样形成粒子逐渐远离直至消失的效果
//! [0]
shape: EllipseShape {fill: false} // 以椭圆形状覆盖。fill: false 表示仅覆盖边缘
velocity: TargetDirection { // 不同于PointDirection,AngleDirection,这里使用了TargetDirection(目标方向),另一个未登场的是CumulativeDirection(累加方向)。 这4个类型一般来说已经足以解决我们的问题
targetX: root.width/2 // 目标点X坐标
targetY: root.height/2 // 目标点Y坐标
proportionalMagnitude: true // 假设该值为false,magnitude的值为粒子每秒移动的像素值。假设被设置为true,则这样计算:
magnitude: 0.5 // 比方此处粒子的产生点为(360,270),目标点为(180,270)。那么移动速度为180*0.5,即每秒90个像素值,这样刚好在粒子两秒的生命周期内达到中心点。
}
//! [0]
} Emitter { // 这个Emitter产生周围飘散的粒子
anchors.fill: parent
group: "edge"
startTime: 2000 // 这个属性设置使得程序一開始就行展示两秒后的效果,这样就略过了粒子生成的过程
emitRate: 2000
lifeSpan: 2000
size: 28
sizeVariation: 2
endSize: 16
shape: EllipseShape {fill: false}
velocity: TargetDirection {
targetX: root.width/2
targetY: root.height/2
proportionalMagnitude: true
magnitude: 0.1 // 同上面所说,这里的0.1使得这些粒子仅仅能运动36个像素点便消逝掉
magnitudeVariation: 0.1 // 设置这个属性使得不必全部粒子运动速度都同样
}
acceleration: TargetDirection { // 同样可将TargetDirection应用于加速度
targetX: root.width/2
targetY: root.height/2
targetVariation: 200 // 目标速度
proportionalMagnitude: true
magnitude: 0.1
magnitudeVariation: 0.1
}
}
}
}

(7)TrailEmitter

这个样例展示了怎样使用TrailEmitter构建尾随粒子,并创建了一个火焰场景。

trailemitter:

import QtQuick 2.0
import QtQuick.Particles 2.0 Rectangle {
id: root
width: 360
height: 540
color: "black" ParticleSystem {
id: particles
anchors.fill: parent ImageParticle { // 这次我们在系统中创建了2种图像粒子,并进行分组以用在不同的位置上
id: smoke
system: particles
anchors.fill: parent
groups: ["A", "B"]
source: "qrc:///particleresources/glowdot.png"
colorVariation: 0
color: "#00111111" // 灰色
}
ImageParticle {
id: flame
anchors.fill: parent
system: particles
groups: ["C", "D"]
source: "qrc:///particleresources/glowdot.png"
colorVariation: 0.1
color: "#00ff400f" // 橘红
} Emitter { // 我们先取C组橘红粒子来创建底部的火焰
id: fire
system: particles
group: "C" y: parent.height
width: parent.width emitRate: 350
lifeSpan: 3500 acceleration: PointDirection {y: -17; xVariation: 3 } // 使粒子向上漂移。并能够轻微地左右摆动
velocity: PointDirection { xVariation: 3} size: 24
sizeVariation: 8
endSize: 4
} TrailEmitter { // TrailEmitter相似Emitter。可是用来创建尾随粒子
id: fireSmoke
group: "B" // 本身粒子种类
system: particles
follow: "C" // 尾随粒子种类
width: root.width
height: root.height - 68 // 使下方火焰区域内不会出现烟雾 emitRatePerParticle: 1 // 尾随粒子发射的比率
lifeSpan: 2000 velocity: PointDirection {y:-17*6; yVariation: -17; xVariation: 3}
acceleration: PointDirection {xVariation: 3} size: 36
sizeVariation: 8
endSize: 16
} TrailEmitter { // 串起的火苗
id: fireballFlame
anchors.fill: parent
system: particles
group: "D"
follow: "E" emitRatePerParticle: 120 // 因为这里的尾随粒子未定义速度与加速度。因此在出现后就被固定了。但我们依旧能够靠产生和消逝实现动画
lifeSpan: 180 // 因此这里的生命周期特别短。假设要实现一长条火焰。能够增大这个数值
emitWidth: TrailEmitter.ParticleSize
emitHeight: TrailEmitter.ParticleSize
emitShape: EllipseShape{} // 设置尾随区域 size: 16
sizeVariation: 4
endSize: 4
} TrailEmitter {
id: fireballSmoke
anchors.fill: parent
system: particles
group: "A"
follow: "E" emitRatePerParticle: 128
lifeSpan: 2400 // 因为烟雾须要有自己的运动轨迹,因此生命周期较火苗更长
emitWidth: TrailEmitter.ParticleSize
emitHeight: TrailEmitter.ParticleSize
emitShape: EllipseShape{} velocity: PointDirection {yVariation: 16; xVariation: 16} // 刚产生的烟雾向下执行。随之慢慢向上升腾
acceleration: PointDirection {y: -16} size: 24
sizeVariation: 8
endSize: 8
} Emitter { // 注意这个Emitter所用的样例组"E"是不存在的,所以实际上它仅仅是一个引导A和D的框架。 假设想要清楚地看出这段代码的工作状态,大家能够自己创建一个绿色的图像粒子,并命名群组为E。 id: balls
system: particles
group: "E" y: parent.height
width: parent.width emitRate: 2
lifeSpan: 7000 velocity: PointDirection {y:-17*4*2; xVariation: 6*6} // 向上的速度以及向下的加速度
acceleration: PointDirection {y: 17*2; xVariation: 6*6} // 使火焰得以腾起,然后下落消失 size: 8
sizeVariation: 4
} Turbulence { // 最后,为烟雾加上一点气流效果,就像它被风吹着一样,这样带来更好的效果
anchors.fill: parent
groups: ["A","B"]
strength: 32
system: particles
}
}
}

本系列下一篇文章:Qt5官方demo分析集11——Qt
Quick Particles Examples - Affectors

Qt5官方demo分析集10——Qt Quick Particles Examples - Emitters的更多相关文章

  1. Qt5官方demo分析集11——Qt Quick Particles Examples - Affectors

    在这个系列中的所有文章都可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文Qt5官方demo解析集10--Qt ...

  2. Qt5官方demo解析集13——Qt Quick Particles Examples - Image Particles

    本系列全部文章能够在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文 Qt5官方demo解析集12--Qt Quic ...

  3. Qt5官方demo分析集29——Extending QML - Property Value Source Example

    此系列的所有文章都可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文Qt5官方demo解析集28--Extend ...

  4. Qt5官方demo解析集30——Extending QML - Binding Example

    本系列全部文章能够在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文Qt5官方demo解析集29--Extendin ...

  5. Qt5官方demo解析集28——Extending QML - Signal Support Example

    本系列全部文章能够在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文Qt5官方demo解析集27--Extendin ...

  6. Qt5官方demo解析集35——Music Player(使用winextras模块)

    本系列所有文章可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文Qt5官方demo解析集34——Concentr ...

  7. Qt5官方demo解析集(36个)

    http://blog.csdn.net/cloud_castle/article/category/2123873 http://blog.csdn.net/cloud_castle/article ...

  8. Qt5官方demo解析集21——Extending QML - Adding Types Example

    本系列全部文章能够在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 又是一个新的系列了,只是这个系列和我们之前的Chapt ...

  9. RobotFramework 官方demo Quick Start Guide rst配置文件分析

    RobotFramework官方demo Quick Start Guide rst配置文件分析   by:授客 QQ:1033553122     博客:http://blog.sina.com.c ...

随机推荐

  1. Qt 信号-槽的同步与异步处理

    通常使用的connect,实际上最后一个參数使用的是Qt::AutoConnection类型:Qt支持6种连接方式.当中3中最主要: 1.Qt::DirectConnection(直连方式)(信号与槽 ...

  2. signature.html

    原文网址:http://www.youdzone.com/signature.html   阮一峰:http://www.ruanyifeng.com/blog/2011/08/what_is_a_d ...

  3. perl对比两个文件的行

    perl对比两个文件的行 对比两个文件的各行,得到A与B相同的行/A与B不相同的行 主要功能 得到相同行 得到A中包含,B不包含的行 得到B中包含,A中不包含的行 具体执行情况 Perl代码 #!/u ...

  4. [Docker] Download and Remove Docker Images

    Learn the basics of downloading and pulling Docker images from Docker Hub. Learn the difference betw ...

  5. copy 和 MutableCopy

    1:copy拷贝得到的对象都是不可变对象,MutableCopy拷贝得到的对象都是可变对象.MutableCopy拷贝得到的对象都是新的对象,会重新分配内存地址,而copy拷贝的对象既可以是新对象,也 ...

  6. 超级牛X的免费开源小工具之tldr

    github介绍:http://tldr-pages.github.io/ github源码:https://github.com/tldr-pages/tldr 什么是tldr? 新命令行世界?还是 ...

  7. php 字符串 去掉 html标签

    echo strip_tags("Hello <b>world!</b>");

  8. Global Git ignore - Stack Overflow

    https://stackoverflow.com/questions/7335420/global-git-ignore git config --global core.excludesfile ...

  9. [Grid Layout] Use the repeat function to efficiently write grid-template values

    We can use the repeat() function if we have repeating specifications for columns and rows. With the  ...

  10. 解决ThinkPad x1 发热的问题

    F1进入BIOS界面 将intel speedstep设置为禁用 将CPU Power Manager设置为禁用 重启电脑 电脑不再发热