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


    本系列全部文章能够在这里查看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:



    好了。代码非常easy,说了这么多,就不讲了哈。allatonce.qml:

    import QtQuick 2.0
    import QtQuick.Particles 2.0
    
    Rectangle {
        color: "white"
         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 {
         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
         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"
         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
        }
    }
    



    (5)Rotation

    我们在上一节中就接触到了rotation,在那个里面rotation用来实现了图片的旋转动画。而这个样例则主要介绍了它的autoRotation - 自己主动转向。

    先看看效果:



    首先是一串从中下向四周发散的海星星,假设屏幕被点击。这些海星星将按其执行轨迹翻转,保证对每一个轨迹而言都是正的。

    rotation.qml:

    import QtQuick 2.0
    import QtQuick.Particles 2.0
    
    Rectangle {
        color: "goldenrod"
         1000
        height: 1000
        ParticleSystem {id: sys}
        ImageParticle {
            id: up
            system: sys
            source: "qrc:/images/starfish_2.png"
            autoRotation: true                  // 这个属性我们前面有谈,再形象一点的话,假设海星星做圆周运动,它的脚会始终指向圆心
            rotation: -90                       // 粒子在自己主动旋转后会再加上这个旋转量,那么就得到了图中海星星对每一个运动方向都为正的效果
        }
    
        Emitter {
            anchors.centerIn: parent
            system: sys
            emitRate: 10
            size: 200
            lifeSpan: 10000
            velocity: AngleDirection {angleVariation: 360; magnitudeVariation: 100;}
        }
    
        MouseArea {
            anchors.fill: parent                      // 实现鼠标点击功能
            onClicked: {
                up.autoRotation = !up.autoRotation
                up.rotation = up.autoRotation ? -90 : 0
            }
        }
    }




    (6)Sharing

    由名字我们就行猜出一些端倪,这个样例向我们展示了怎样在同一个或是同一类粒子中展示不同的ImageParticle的效果。

    同一时候。一个粒子中还可以包括多个ImageParticle中定义的属性。

    因为原例中的文字是白色的。截图看不太清楚,我把它改成了蓝色。只是这并不影响。我们关注的是它的“小花”(粒子)。



    能够看到小花在整个屏幕中都是偏白色,而在我们选中项的高亮中它显示为黑红色。而且它是随着进入的部分而部分变换。这在实际使用中相当经常使用。

    另外还有些listView的操作与动画,但这就不是我们这一节重点啦~

    sharing.qml:

    // This example shows how to create your own highlight delegate for a ListView
    // that uses a SpringAnimation to provide custom movement when the
    // highlight bar is moved between items.
    
    import QtQuick 2.0
    import QtQuick.Particles 2.0
    
    Rectangle {
        property real delegateHeight: 65
         200; height: 300
        gradient: Gradient {
            GradientStop { position: 0.0; color: "#EEEEFF" }
            GradientStop { position: 1.0; color: "lightblue" }
        }
    
        // Define a delegate component.  A component will be
        // instantiated for each visible item in the list.
        Component {                  // 我们须要为listView的每一个可视项目创建一个组件,定义一个组件就相似定义了一个qml文件。这个文件名称就是petDelegate.qml,Item是它的根文件夹。组件中定义的可视化对象不会被直接渲染,除非它被其它类型所载入。
            id: petDelegate          // 在Item外我们仅仅能定义这个id名
            Item {                   // Item作为这个可视化组件的根文件夹
                id: wrapper
                 200; height: delegateHeight        
                z: 10
                Column {
                    Text {color: "blue"; text: name; font.pixelSize: 18 }             // 按列排放的文字
                    Text {color: "blue"; text: 'Type: ' + type; font.pixelSize: 14 }
                    Text {color: "blue"; text: 'Age: ' + age; font.pixelSize: 14 }
                }
                MouseArea { anchors.fill: parent; onClicked: listView.currentIndex = index; } // 被点击则作为当前对象
                // indent the item if it is the current item
                states: State {
                    name: "Current"                            // 设置一个当前状态
                    when: wrapper.ListView.isCurrentItem
                    PropertyChanges { target: wrapper; x: 20 }   // x缩进20
                }
                transitions: Transition {
                    NumberAnimation { properties: "x"; duration: 200 } // 为这个缩进加入一个动画
                }
            }
        }
    
        // Define a highlight with customized movement between items.
        Component {                             // 将高亮显示框也定义为一个组件
            id: highlightBar                    
            Rectangle {                          // Rectangle作为根文件夹
                z: 0
                 200; height: delegateHeight
                gradient: Gradient {
                    GradientStop { position: 0.0; color: "#99FF99" }
                    GradientStop { position: 1.0; color: "#88FF88" }
                }
                y: listView.currentItem.y;       // y坐标与当前项目坐标一致
                Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } } // 为 y 的改变加入一个弹簧动画
                //! [1]
                ImageParticle {                  // 高亮框内的ImageParticle
                    anchors.fill: parent
                    system: particles
                    source: "qrc:/images/flower.png"
                    color: "red"
                    clip: true
                    alpha: 1.0
                }
                //! [1]
            }
        }
    
        ListView {                                
            id: listView
             200; height: parent.height
    
            model: petsModel                   // 指定模型
            delegate: petDelegate              // 指定托付对象
            focus: true
    
            // Set the highlight delegate. Note we must also set highlightFollowsCurrentItem
            // to false so the highlight delegate can control how the highlight is moved.
            highlight: highlightBar            // 指定highlight托付对象
            highlightFollowsCurrentItem: false  // 因为我们要实现自己定义的highlight动画,因此将该属性设置为false
    
            ParticleSystem { id: particles }    // ParticleSystem
            Emitter {                           // Emitter
                system: particles
                anchors.fill: parent
                emitRate: 0
                lifeSpan: 10000
                size: 24
                sizeVariation: 8
                velocity: AngleDirection { angleVariation: 360; magnitude: 3 }
                maximumEmitted: 10
                startTime: 5000                   // 这个属性我们之前接触过了,它使Emitter被载入使直接显示5秒后的效果
                Timer { running: true; interval: 10; onTriggered: parent.emitRate = 1; }
            }
    
            //! [0]
            ImageParticle {                      // 通用粒子,它覆盖了整个ListView,因此Emitter发射的粒子大部分通过它渲染
                anchors.fill: parent             // 可是当Emitter发射的粒子在高亮区域中时,它将转而使用highlight中的ImageParticle
                system: particles                // 因此粒子颜色与透明度都被改变了
                source: "qrc:/images/flower.png" // 但因为highlight中的ImageParticle中的rotation未被设置
                alpha: 0.1                       // 因此粒子将继续採用此处的rotationVariation: 180
                color: "white"                   // 这也就是ImageParticle中的属性共享
                rotationVariation: 180
                z: -1
            }
            //! [0]
        }
    
        ListModel {                              // 为ListView提供数据
            id: petsModel
            ListElement {
                name: "Polly"
                type: "Parrot"
                age: 12
                size: "Small"
            }
            ListElement {
                name: "Penny"
                type: "Turtle"
                age: 4
                size: "Small"
            }
            ListElement {
                name: "Warren"
                type: "Rabbit"
                age: 2
                size: "Small"
            }
            ListElement {
                name: "Spot"
                type: "Dog"
                age: 9
                size: "Medium"
            }
            ListElement {
                name: "Schrödinger"
                type: "Cat"
                age: 2
                size: "Medium"
            }
            ListElement {
                name: "Joey"
                type: "Kangaroo"
                age: 1
                size: "Medium"
            }
            ListElement {
                name: "Kimba"
                type: "Bunny"
                age: 65
                size: "Large"
            }
            ListElement {
                name: "Rover"
                type: "Dog"
                age: 5
                size: "Large"
            }
            ListElement {
                name: "Tiny"
                type: "Elephant"
                age: 15
                size: "Large"
            }
        }
    
    }



    (7)Sprites

    sprites大家都不陌生了。我们在前面的程序中大量接触到了这个东西。使用它要比使用GIF节省多得多的性能,而且与粒子系统一同工作,可以创造动态性能相当高的应用程序。



    能够看到以下有仅仅会动的小熊,上方掉落的海星星也在不断变化着表情。

    当下落到小熊附近时,它们将变成萌萌哒的"惊喜"表情。

    sprites.qml:

    import QtQuick 2.0
    import QtQuick.Particles 2.0
    
    Rectangle {
        color: "lightsteelblue"
         800
        height: 800
        id: root
    
        SpriteSequence {                                     // 该类型提供了一个机遇sprite的动画
            sprites: Sprite {
                    name: "bear"
                    source: "qrc:/images/bear_tiles.png"           // 图片贴在下方
                    frameCount: 13
                    frameDuration: 120
                }
             250                                      // 定义小熊的位置与层次
            height: 250
            x: 20
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 20
            z:4
        }
    
        ParticleSystem { id: sys }
    
        ImageParticle {
            anchors.fill: parent
            id: particles
            system: sys
            sprites: [Sprite {                               // 定义各种状态的海星星。并等概率相互转换
                name: "happy"
                source: "qrc:/images/starfish_1.png"
                frameCount: 1
                frameDuration: 260
                to: {"happy": 1, "silly": 1, "angry": 1}
            }, Sprite {
                name: "angry"
                source: "qrc:/images/starfish_0.png"
                frameCount: 1
                frameDuration: 260
                to: {"happy": 1, "silly": 1, "angry": 1}
            }, Sprite {
                name: "silly"
                source: "qrc:/images/starfish_2.png"
                frameCount: 1
                frameDuration: 260
                to: {"happy": 1, "silly": 1, "noticedbear": 0}
            }, Sprite {                                        // 在通常情况下,"noticedbear"状态无法达到
                name: "noticedbear"
                source: "qrc:/images/starfish_3.png"
                frameCount: 1
                frameDuration: 2600
            }]
        }
    
        Emitter {                                      // 海星星的发射器
            system: sys
            emitRate: 2
            lifeSpan: 10000
            velocity: AngleDirection {angle: 90; magnitude: 60; angleVariation: 5}
            acceleration: PointDirection { y: 10 }
            size: 160
            sizeVariation: 40
             parent.width
            height: 100
        }
    
        SpriteGoal {                             // 最后定义一个SpriteGoal使海星星在运动到矩形的左下部分时跳转到"noticedbear"状态
            system: sys
             root.width;
            height: root.height/2;
            y: root.height/2;
            goalState:"noticedbear"
        }
    }


    这里将小熊的sprite图贴下:

  • 相关阅读:
    layer ----- 弹层
    php start
    node.js使用iconv-lite和zlib解决gzip压缩和gbk乱码
    AngularJS中promise的使用
    AngularJS中的$routeProvider
    AngularJS入门教程记录
    AngularJS中的$resource
    Javascript原型易错点记录
    触屏相关事件问题记录
    图片预加载
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/7189537.html
Copyright © 2020-2023  润新知