首页 > 代码库 > Qt5官方demo解析集13——Qt Quick Particles Examples - Image Particles

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

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

接上文 Qt5官方demo解析集12——Qt Quick Particles Examples - CustomParticles


先唠下嗑,在上文CustomParticles中我们接触了强大的ShaderEffect,笔者对其产生了极大的兴趣,于是去找了找有没有更多相关的例程,于是就发现了一个QML Video Shader Effects Example,确实效果华丽,下面放个图,回头再看看这个demo~


这个demo可以处理图片、视频以及摄像头数据,算是非常强大的功能了。不过在手机上运行时布局似乎有些问题。



好了,不扯远了,这次的demo又回归了ImageParticle,相信大家都不陌生了。这个demo应该比上一个要轻松,我们来看看吧:

依旧是熟悉的选择框:



(1)All at once

这个例子演示了一群旋转的小熊。下面有一行话,“QML这么叼你敢信吗...”



确实是五彩缤纷哈,怎么来形成多彩的效果呢?可能你马上会想到ImageParticle中的colorVariation这个属性,将这个值设高不就能形成多彩的效果吗?确实不错,但是如果我们要求这个小熊只在几种颜色之间变化呢?例如橘红,红色,青色,绿色,和黄色?或者再多一点,连随机数取值也不好做?那么ImageParticle为我们提供了一个属性colorTable,这个属性使得我们可以在一个一维纹理中取出颜色值赋予图像。我们通过自定义一个合适的一维图像就可以决定小熊的颜色了。

这里我将colorVariation设置为1,可以看下对比效果:


可以看到颜色确实更加丰富,但由于本身的一维图像是带有透明度的,想要模仿原例的效果,我们还需要设置透明度:

这里将alpha设置为0.5:



好了,代码很简单,说了这么多,就不讲了哈。allatonce.qml:

import QtQuick 2.0
import QtQuick.Particles 2.0

Rectangle {
    color: "white"
    width: 640
    height: 480
    ParticleSystem {
        id: sys
    }

    ImageParticle {
        // ![0]
        sprites: [
            Sprite {
                name: "bear"
                source: "qrc:/images/bear_tiles.png"
                frameCount: 13
                frameDuration: 120
            }
        ]
        colorVariation: 0.5
        rotationVelocityVariation: 360
        colorTable: "qrc:/images/colortable.png"
        // ![0]
        system: sys
    }

    Friction {
        factor: 0.1
        system: sys
    }

    Emitter {
        system: sys
        anchors.centerIn: parent
        id: particles
        emitRate: 200
        lifeSpan: 6000
        velocity: AngleDirection {angleVariation: 360; magnitude: 80; magnitudeVariation: 40}
        size: 60
        endSize: 120
    }

    Text {
        x: 16
        y: 16
        text: "QML..."
        style: Text.Outline; styleColor: "#AAAAAA"
        font.pixelSize: 32
    }
    Text {
        anchors.bottom: parent.bottom
        anchors.right: parent.right
        anchors.margins: 16
        text: "... can you be trusted with the power?"
        style: Text.Outline; styleColor: "#AAAAAA"
        font.pixelSize: width > 400 ? 32 : 16
    }
}


我将colortable的图贴在下面:

”  < - 就在这里。它纵向只有一个像素,很窄。


(2)Colored

这个例子展示了两种星星的效果。



colored.qml:

import QtQuick 2.0
import QtQuick.Particles 2.0

Rectangle {
    width: 360
    height: 540
    color: "black"
    ParticleSystem {
        anchors.fill: parent
        ImageParticle {                                 // 背景星星
            groups: ["stars"]
            anchors.fill: parent
            source: "qrc:///particleresources/star.png"
        }
        Emitter {
            group: "stars"
            emitRate: 800
            lifeSpan: 2400
            size: 24
            sizeVariation: 8
            anchors.fill: parent                       // 布满父对象的背景星星
        }

        // ![0]
        ImageParticle {                               // 没有定义的group默认为""
            anchors.fill: parent
            source: "qrc:///particleresources/star.png"
            alpha: 0
            alphaVariation: 0.2                        // 多彩与透明效果
            colorVariation: 1.0
        }
        // ![0]

        Emitter {                                     // 默认发射group名为""的粒子
            anchors.centerIn: parent
            emitRate: 400
            lifeSpan: 2400
            size: 48
            sizeVariation: 8
            velocity: AngleDirection {angleVariation: 180; magnitude: 60} // 180的变化度,即是(-180,180)
        }

        Turbulence {                                    // 最后添加一些气流效果
            anchors.fill: parent
            strength: 2
        }
    }
}



(3)Color Table

从名字可以知道这里例子着重介绍了colorTable这个属性。



可以看到3个光束以类似∞的轨迹运行,colortable.qml:

Rectangle {
    id: root
    width: 360
    height: 540
    color: "black"

    ParticleSystem { id: particles }

    ImageParticle {
        system: particles
        colorVariation: 0.5
        alpha: 0

        //! [0]
        source: "qrc:///particleresources/glowdot.png"
        colorTable: "qrc:/images/colortable.png"      // 这个与例子一相同
        sizeTable: "qrc:/images/colortable.png"      // 有意思的是,我们可以使用这个一维图像的透明度来决定粒子的尺寸,根据Manual所说,这个属性将在之后被移除,取而代之的是使用自定义的缓和曲线
        //! [0]
    }

    Emitter {
        system: particles
        emitRate: 500
        lifeSpan: 2000

        y: root.height / 2 + Math.sin(t * 2) * root.height * 0.3 // 定义了一个类似∞的轨迹,删掉t中的2,它将变成一个椭圆
        x: root.width / 2 + Math.cos(t) * root.width * 0.3
        property real t;

        NumberAnimation on t {
            from: 0; to: Math.PI * 2; duration: 10000; loops: Animation.Infinite
        }

        velocityFromMovement: 20

        velocity: PointDirection { xVariation: 5; yVariation: 5;}     // 有一定的四周消散能力
        acceleration: PointDirection { xVariation: 5; yVariation: 5;}

        size: 16
        //endSize: 8
        //sizeVariation: 8
    }
}
关于为什么会形成3个光束:这里的粒子实际上是按轨迹不断生成的,新的粒子产生,旧的粒子还未消散,形成了一条光束。而这些粒子随着生命周期的变化,其颜色、透明度以及尺寸都是与这个colortable一维图像相关的,这个图像我在上面贴出来了,其中间几段有很明显的透明区域,当粒子达到与之相对应的生命周期,我们也就看不到了,随着生命周期的推进,它们又以其他的颜色展现出来。



(4)Deformation

这一节主要介绍了ImageParticle的变形,主要是旋转以及伸缩。上面两排海星星在旋转,下面的海星星被压缩。



deformation.qml:

import QtQuick 2.0
import QtQuick.Particles 2.0

Rectangle {
    color: "goldenrod"
    width: 400
    height: 400
    ParticleSystem {id:sys}

    //! [spin]
    ImageParticle {
        system: sys
        groups: ["goingLeft", "goingRight"]
        source: "qrc:/images/starfish_4.png"
        rotation: 90                          // (顺时针)旋转90度
        rotationVelocity: 90                  // 旋转速度
        autoRotation: true
    }
    //! [spin]
    //! [deform]
    ImageParticle {
        system: sys
        groups: ["goingDown"]
        source: "qrc:/images/starfish_0.png"      // 换了一张图,这个星星不开心些
        rotation: 180                            // 旋转180度,倒过来了
        yVector: PointDirection { y: 0.5; yVariation: 0.25; xVariation: 0.25; } // yVector参数是一个矢量,也就是说我们不仅可以压缩这个图像,还能使它任意拉伸(想象我们拉住一个四边形的两个角任意拉扯的效果)。
    }
    //! [deform]

    Timer {
        running: true                       // 几个定时器用来发射粒子
        repeat: false
        interval: 100
        onTriggered: emitA.enabled = true;
    }
    Timer {
        running: true
        repeat: false
        interval: 4200
        onTriggered: emitB.enabled = true;
    }
    Timer {
        running: true
        repeat: false
        interval: 8400
        onTriggered: emitC.enabled = true;
    }

    Emitter {                                 // 发射器,如果不清楚可以参考前面的博文
        id: emitA
        x: 0
        y: 120
        system: sys
        enabled: false
        group: "goingRight"
        velocity: PointDirection { x: 100 }
        lifeSpan: 4000
        emitRate: 1
        size: 128
    }
    Emitter {
        id: emitB
        x: 400
        y: 240
        system: sys
        enabled: false
        group: "goingLeft"
        velocity: PointDirection { x: -100 }
        lifeSpan: 4000
        emitRate: 1
        size: 128
    }
    Emitter {
        id: emitC
        x: 0
        y: 360
        system: sys
        enabled: false
        group: "goingDown"
        velocity: PointDirection { x: 100 }
        lifeSpan: 4000
        emitRate: 1
        size: 128
    }
}



(4)Rotation

待更新