Qt Quick Particles 示例 - 系统

本部分汇集了在 QML 粒子系统中使用 Affectors 的示例。

蓝色背景上带有黑色边框的圆形颗粒,展示了多位画家

这是一组与粒子系统中使用“影响器”(Affectors)相关的小型 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 对象无法实现随机着色。

“Start”和“Stop”仅用于设置ParticleSystem 的运行和暂停状态。虽然系统在停止或暂停时不会进行任何模拟,但“Restart”会从头开始重新启动模拟,而“Unpause”则从暂停前的位置继续模拟。

“定时组切换”是一个突出展示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作为直接子节点,这使得该Affector自动将该组设为目标。Affector的作用是:一旦粒子进入该组,即可根据该粒子的x、y坐标,调用另一个发射器的burst函数。

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

如果“TrailEmitter ”无法满足您对多个发射器的需求,您也可以在继续使用同一ParticleSystem 和图像粒子(image particle)的同时,动态创建发射器(Emitters)

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 对象遵循常规的 Z 排序规则 Qt Quick 。本示例允许您使用一对 ImageParticles 绘制黑色边框上方的粒子内部,每个 ImageParticle 分别绘制同一逻辑粒子的不同部分。

示例项目 @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.