QML粒子系统-Emitter(5)

413 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 8 天,点击查看活动详情


📒博客首页:何名取 的个人主页 - 文章 - 掘金 (juejin.cn)
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
❤️ 期待一起交流!
🙏作者水平很有限,如果发现错误,求告知,多谢!
🌺有问题可私信交流!!!


Emitter的属性探究之三

前言

前四篇发射器Emitter的文章已经基本将发射器讲完了,剩下的只有maximumEmitted和velocityFromMovement属性。maximumEmitted属性其实是限制当前窗口最大的发射粒子数,我之前使用发射器的时候Qt的IDE报过错误,好像最多只能一次发射16000多个粒子。maximumEmitted属性在我们使用发射器时可以做一个限定。最后的velocityFromMovement属性就是本节要讲解的内容。

velocityFromMovement属性

前面的文章中有Emitter的属性列表,这里单独再详细解释一下这个属性。

velocityFromMovement : qreal
如果这个值是非零,那么发射器的任何移动都将基于移动为粒子提供额外的起始速度。额外的矢量将与发射器的运动相同的角度,其大小是发射器运动的大小乘以velocityFromMovement。
默认值为0。

这里的说的意思直观理解就是当一个发射器做圆周运动时,由它发射出去的粒子会与其形成切线运动。如果这句话还不好理解,下面的例子将会以动图的形式为您展示。

实战

设计思路

构建一个粒子系统。

粒子系统是构成整个粒子效果的基础,包含了渲染器和发射器。

ParticleSystem { id: sys1 }
ImageParticle {
            system: sys1
            ...
}
Emitter {
            system: sys1
            ...
}

构建一个图片粒子渲染器。

渲染器描绘了发射器中发射出的粒子的形状、颜色。

构建粒子渲染器时,使用了渐变动效,使得粒子颜色从初始颜色缓慢进行变化。本节暂时不详细介绍动效的使用。

构建一个发射器。

发射器是本节的重点,其中主要探究velocityFromMovement属性的使用方法。velocityFromMovement属性描述中讲到在发射器移动时会将其速度和属性值进行相乘,赋予粒子额外的速度。因此,在本节中需要对发射器的x、y坐标进行改变,使发射器能够移动产生速度。

        Emitter {
            id: trailsNormal
            system: sys1

            emitRate: 500
            lifeSpan: 2000

            y: circle.cy
            x: circle.cx

            velocity: PointDirection {xVariation: 4; yVariation: 4;}
            acceleration: PointDirection {xVariation: 10; yVariation: 10;}
            velocityFromMovement: 8

            size: 12
            sizeVariation: 4
        }
        //! [0]

构建一个做环绕运动的item。

此item与发射器结合,将会使发射器的位置进行不断的环绕运动,在运动过程中将会展示velocityFromMovement属性的作用。

在构建环绕运动的item时,需要对运动的坐标进行描绘。首先使其做顺时针圆周运动,接着做逆时针圆周运动。其次将半径大小做线性变化,使圆周运动变化为螺旋环绕运动。

完整代码

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Particles 2.2

Window {
    width: 640
    height: 640
    visible: true
    title: qsTr("emitter motion")

    Rectangle {
        id: root
        anchors.fill: parent

        gradient: Gradient {
            GradientStop { position: 0; color: "#000020" }
            GradientStop { position: 1; color: "#000000" }
        }

        ParticleSystem { id: sys1 }
        ImageParticle {
            system: sys1
            source: "qrc:///particleresources/glowdot.png"
            color: "cyan"
            alpha: 0
            SequentialAnimation on color {
                loops: Animation.Infinite
                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]
        Emitter {
            id: trailsNormal
            system: sys1

            emitRate: 500
            lifeSpan: 2000

            y: circle.cy
            x: circle.cx

            velocity: PointDirection {xVariation: 4; yVariation: 4;}
            acceleration: PointDirection {xVariation: 10; yVariation: 10;}
            velocityFromMovement: 8

            size: 12
            sizeVariation: 4
        }
        //! [0]

        color: "white"

        Item {
            id: circle

            property real radius: 0
            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 {
                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: 200
                }
                NumberAnimation {
                    duration: 4000
                    from: 200
                    to: 0
                }
            }
        }
    }
}

效果展示

图片大小限制,无法录制太长的GIF,小伙伴们可以将代码复制到自己的工程中运行查看。 motion.gif 从图上可以看出,粒子被发射后呈现甩出的效果,这个效果就是velocityFromMovement属性的作用了。