Qt Quick 粒子系统示例 - 系统#

这是一系列使用 QML 粒子系统中的 Affector 的示例。

../_images/qml-system-example.png

这是一系列关于在粒子系统中使用 Affector 的 QML 短例。每个示例都是一个简单的 QML 文件,强调了特定类型或功能。

动态比较是通过动态实例化 Image 类型来获取类似效果的粒子系统用法。

Item {
    id: fakeEmitter
    function burst(number) {
        while (number > 0) {
            let item = fakeParticle.createObject(root)
            item.lifeSpan = Math.random() * 5000 + 5000
            item.x = Math.random() * (root.width / 2) + (root.width / 2)
            item.y = 0
            number--
        }
    }

    Component {
        id: fakeParticle
        Image {
            id: container
            property int lifeSpan: 10000
            width: 32
            height: 32
            source: "qrc:///particleresources/glowdot.png"
            PropertyAnimation on y { from: -16; to: root.height - 16; duration: container.lifeSpan; running: true }
            SequentialAnimation on opacity {
                running: true
                NumberAnimation { from: 0; to: 1; duration: 500 }
                PauseAnimation { duration: container.lifeSpan - 1000 }
                NumberAnimation { from: 1; to: 0; duration: 500 }
                ScriptAction { script: container.destroy(); }
            }
        }
    }
}

注意 Image 对象无法随机着色。

开始和停止简单设置 ParticleSystem 的运行和暂停状态。在停止或暂停时,系统不会进行任何模拟,但是重新启动会从开始重新启动模拟,而取消暂停会从暂停的位置继续。

定时组更改是一个突出 ParticleGroup 类型示例。虽然通常使用字符串名称引用组是足够的,但通过在组上设置属性,可以实现额外的效果。第一个组具有可变持续时间,但总是会过渡到第二个组。

ParticleGroup {
    name: "fire"
    duration: 2000
    durationVariation: 2000
    to: {"splode":1}
}

第二个组上有一个 TrailEmitter,并且发射到第三个组有一个固定持续时间。通过将 TrailEmitter 作为 ParticleGroup 的直接子项,它可以自动选择该组进行跟踪。

ParticleGroup {
    name: "splode"
    duration: 400
    to: {"dead":1}
    TrailEmitter {
        group: "works"
        emitRatePerParticle: 100
        lifeSpan: 1000
        maximumEmitted: 1200
        size: 8
        velocity: AngleDirection {angle: 270; angleVariation: 45; magnitude: 20; magnitudeVariation: 20;}
        acceleration: PointDirection {y:100; yVariation: 20}
    }
}

第三个组有一个 Affector 作为直接子项,这意味着一旦粒子进入该组,就可以在其他发射器上调用爆发的功能,使用该粒子的 x,y 位置。

ParticleGroup {
    name: "dead"
    duration: 1000
    Affector {
        once: true
        onAffected: (x, y)=> worksEmitter.burst(400,x,y)
    }
}

如果 TrailEmitter 不适用于您的多发射器需求,您也可以在仍使用相同的 ParticleSystem 和图像粒子的情况下动态创建发射器。

for (var i = 0; i < 8; i++) {
    let obj = emitterComp.createObject(root)
    obj.x = x
    obj.y = y
    obj.targetX = Math.random() * 240 - 120 + obj.x
    obj.targetY = Math.random() * 240 - 120 + obj.y
    obj.life = Math.round(Math.random() * 2400) + 200
    obj.emitRate = Math.round(Math.random() * 32) + 32
    obj.go()
}

请注意,这个效果,一连串的彩虹尖矛,最好使用 TrailEmitter 来实现。这个示例只用动态发射器来实现,以更简单地展示这个概念。

多个画家展示了如何控制单个粒子的绘制顺序。虽然一个 ImagePainter 中的粒子的绘制顺序并不是严格定义的,ImageParticle 对象遵循 Qt Quick 项的正常 Z-顺序规则。该示例允许您使用成对的 ImageParticles (每个 ImageParticle 绘制同一个逻辑粒子的不同部分),将粒子内部绘制在黑色边框之上。

示例项目 @ code.qt.io