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

Qt5官方demo解析集11——Qt Quick Particles Examples - Affectors

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

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


Affectors是Qt官方粒子系统demo中的第二个例程,它是在Emitters上的进一步扩展。我们将看到,通过使用Affectors,我们能够创造更加灵活的粒子显示以及交互行为。

首先还是看下介绍:This is a collection of small QML examples relating to using Affectors in the particle system. Each example is a small QML file emphasizing a particular type or feature.

很简短,告诉我们这个demo依然是由多个使用Affectors的小例子构成。运行后是同样的选择框:


一共有10个例子,我们还是从第一个开始:


(1)Age

来看看<“杀掉”进入Affector的粒子>是个什么效果:进入图中矩形框的雪花都变小并逐渐消失了。



来看看这个小例子是怎么写的吧~ age.qml:

import QtQuick 2.0
import QtQuick.Particles 2.0

Rectangle {
    id: root
    width: 360
    height: 600
    color: "white"

    ParticleSystem { id: particles }

    ImageParticle {            // 这里向我们展示另外一种图像粒子的设置
        system: particles
        sprites: Sprite {      // sprites属性用来定义一组帧图片来作为粒子,这样粒子可以像GIF一样拥有自己的动画
            name: "snow"
            source: "../../images/snowflake.png"  // 这是一张具有51帧的雪花图形
            frameCount: 51
            frameDuration: 40                     // 帧动画的基本设置
            frameDurationVariation: 8
        }
    }

    Emitter {
        system: particles
        emitRate: 20
        lifeSpan: 8000
        velocity: PointDirection { y:80; yVariation: 40; }  // 加速度下落
        acceleration: PointDirection { y: 4 }
        size: 36
        endSize: 12
        sizeVariation: 8
        width: parent.width
        height: 100
    }

    MouseArea {
        id: ma
        anchors.fill: parent
        hoverEnabled: true
    }

    Rectangle {                   // 这里使用Rectangle作为Age的父类,当然Age可以定义自己的坐标以及区域,但是加入Rectangle可视化效果更好
        color: "#803333AA"                        // 半透明的湛蓝色
        border.color: "black"
        x: ma.mouseX - 36                         // 这里用到属性绑定使得该矩形可以跟随鼠标的移动,并以鼠标为中心点
        y: ma.mouseY - 36
        width: 72
        height: 72
        //! [0]
        Age {                         // Age继承自Affector,其实在上一篇Emitters中我们就接触了一个Affector:Turbulence,它可以提供一个气流的效果,而这里的Age则允许我们改变粒子的生命周期。
            anchors.fill: parent    
            system: particles
            once: true                // 每个粒子只影响一次
            lifeLeft: 1200            // 粒子剩下的时间
            advancePosition: false    // 退化是否影响位置、速度、和加速度
        }
        //! [0]
    }
}

雪花图太长,截一部分好了:



(2)Attractor

这个小例子使用Affector中的Attractor(吸引者)向我们展示了如何使用粒子系统模拟一个黑洞。



可以看到图中心有一个“黑洞”,靠近黑洞的粒子会被改变运行轨迹,太近的粒子会被吸进去。如果需要我们自己来写这种速度改变的代码可能会相当繁琐,好在QtQuick给我们提供了Attractor这个Affector,来看看它怎么使用的~attractor.qml

import QtQuick 2.0
import QtQuick.Particles 2.0
Rectangle {
    id: root
    width: 360
    height: 540
    color: "black"
    Image {
        source: "qrc:/images/finalfrontier.png"
        anchors.centerIn:parent
    }
    ParticleSystem {
        id: particles
        anchors.fill: parent
        Emitter {                    // 星星发射器
            group: "stars"
            emitRate: 40
            lifeSpan: 4000
            enabled: true
            size: 30
            sizeVariation: 10
            velocity: PointDirection { x: 220; xVariation: 40 }
            height: parent.height  // height定义了发射发射区域的高度,否则粒子从(0,0)发出
        }
        Emitter {                    // 陨石发射器
            group: "roids"
            emitRate: 10
            lifeSpan: 4000
            enabled: true
            size: 30
            sizeVariation: 10
            velocity: PointDirection { x: 220; xVariation: 40 }
            height: parent.height
        }
        ImageParticle {              // 星星
            id: stars
            groups: ["stars"]
            source: "qrc:///particleresources/star.png"
            color: "white"
            colorVariation: 0.5
            alpha: 0
        }
        ImageParticle {              // 陨石
            id: roids
            groups: ["roids"]
            sprites: Sprite {      // 这里再次使用了帧动画,由于没有定义frameDurationVariation,所有陨石的旋转速度都是相同的
                id: spinState
                name: "spinning"
                source: "qrc:/images/meteor.png"
                frameCount: 35
                frameDuration: 60
            }
        }
        ImageParticle {             // 飞船子弹
            id: shot
            groups: ["shot"]
            source: "qrc:///particleresources/star.png"
            color: "#0FF06600"
            colorVariation: 0.3
        }
        ImageParticle {             // 尾气
            id: engine
            groups: ["engine"]
            source: "qrc:///particleresources/fuzzydot.png"
            color: "orange"
            SequentialAnimation on color {        // 属性动画
                loops: Animation.Infinite
                ColorAnimation {
                    from: "red"
                    to: "cyan"
                    duration: 1000
                }
                ColorAnimation {
                    from: "cyan"
                    to: "red"
                    duration: 1000
                }
            }
            colorVariation: 0.2
        }
        //! [0]
        Attractor {                   // Affector家族中的一员,可以形成吸引其他粒子的效果
            id: gs; pointX: root.width/2; pointY: root.height/2; strength: 4000000;   // pointX,pointY是其作为目标点,同其他Affector一样,设置其x,y,height,weidth改变的是其影响区域
            affectedParameter: Attractor.Acceleration           // 设置为影响加速度
            proportionalToDistance: Attractor.InverseQuadratic       // 影响效果与距离的比例关系
        }
        //! [0]
        Age {                        // 在Attractor周围再安装一个Age,因为这里没有设置lifeLeft,粒子进入该区域变消失了
            x: gs.pointX - 8;        // Age的影响区域
            y: gs.pointY - 8;
            width: 16
            height: 16
        }
        Rectangle {                  // 用矩形画圆的方法
            color: "black"
            width: 8
            height: 8
            radius: 4
            x: gs.pointX - 4
            y: gs.pointY - 4
        }
        Image {                        // 飞行器
            source:"qrc:/images/rocket2.png"
            id: ship
            width: 45
            height: 22
            //Automatic movement
            SequentialAnimation on x {             // 属性动画,这里使用了弹线轨迹
                loops: -1
                NumberAnimation{to: root.width-45; easing.type: Easing.InOutQuad; duration: 2000} 
                NumberAnimation{to: 0; easing.type: Easing.OutInQuad; duration: 6000}
            }
            SequentialAnimation on y {
                loops: -1
                NumberAnimation{to: root.height-22; easing.type: Easing.OutInQuad; duration: 6000}
                NumberAnimation{to: 0; easing.type: Easing.InOutQuad; duration: 2000}
            }
        }
        Emitter {                           // 尾气粒子
            group: "engine"
            emitRate: 200
            lifeSpan: 1000
            size: 10
            endSize: 4
            sizeVariation: 4
            velocity: PointDirection { x: -128; xVariation: 32 }
            height: ship.height
            y: ship.y
            x: ship.x
            width: 20
        }
        Emitter {                         // 子弹粒子
            group: "shot"
            emitRate: 32
            lifeSpan: 1000
            enabled: true
            size: 40
            velocity: PointDirection { x: 256; }
            x: ship.x + ship.width
            y: ship.y + ship.height/2
        }
    }
}