本系列所有文章可以在這里查看[http://blog.csdn.net/cloud_castle/article/category/2123873](http://blog.csdn.net/cloud_castle/article/category/2123873)
前段時間去聽了Qt在北京的開發者大會,感覺QML是大勢所趨,所以回來后想好好補補QML方面的東西。無奈無論是書籍還是網絡上,這方面的教材都太少了。
霍亞飛的《Qt Creator快速入門》第二版中做了一些介紹,但也只是基本的元素,布局,動畫等。QML絢麗的粒子特效,傳感器,多媒體模塊,WebView,GPS,藍牙等等...都沒有提及。
所以這段時間也在做Qt官網[QML Applications](http://blog.csdn.net/cloud_castle/article/details/28412867)這個教材的翻譯,大家有興趣的也可以看看。
好了,廢話不多說,我們今天就來看一個 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; }
}
}
}
~~~

(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](http://blog.csdn.net/cloud_castle/article/details/33723715)
- 前言
- 1——Fortune Server/Client
- 2——Multicast Sender/Receiverz
- 3——Broadcast Sender/Receiver
- 4——Blocking Fortune Client
- 5——Threaded Fortune Server
- 5(總結)——Fortune例程的各個實現區別
- 6——Loopback Example
- 7——Analog Clock Example
- 8——Shaped Clock Example
- 9——Analog Clock Window Example
- 10——Qt Quick Particles Examples - Emitters
- 11——Qt Quick Particles Examples - Affectors
- 12——Qt Quick Particles Examples - CustomParticles
- 13——Qt Quick Particles Examples - Image Particles
- 14——Qt Quick Particles Examples - System
- 15——Chapter 1: Creating a New Type
- 16——Chapter 2: Connecting to C++ Methods and Signals
- 17——Chapter 3: Adding Property Bindings
- 18——Chapter 4: Using Custom Property Types
- 19——Chapter 5: Using List Property Types
- 20——Chapter 6: Writing an Extension Plugin
- 21——Extending QML - Adding Types Example
- 22——Extending QML - Object and List Property Types Example
- 23——Extending QML - Inheritance and Coercion Example
- 24——Extending QML - Default Property Example
- 25——Extending QML - Methods Example
- 26——Extending QML - Grouped Properties Example
- 27——Extending QML - Attached Properties Example
- 28——Extending QML - Signal Support Example
- 29——Extending QML - Property Value Source Example
- 30——Extending QML - Binding Example
- 31——StocQt
- 32——Qt Quick Examples - Threading
- 33——Qt Quick Examples - Window and Screen
- 34——Concentric Circles Example
- 35——Music Player
- 36——Wiggly Example
- 37——Vector Deformation