Qt Quick 粒子系统(三):发射器深度解析
2026/6/8 20:49:31 网站建设 项目流程

目录

    • 一、发射器是粒子系统的源头
    • 二、开发环境与版本说明
    • 三、原理分析:三种发射模式
      • 3.1 emitRate 连续发射
      • 3.2 burst(count) 脉冲发射
      • 3.3 pulse(duration) 定时脉冲
      • 3.4 三种模式对比
    • 四、代码实现:Concept_EmitterMethods.qml 逐段解析
      • 4.1 左栏:burst 脉冲发射
      • 4.2 右栏:pulse 定时脉冲
      • 4.3 为什么用两个独立的 ParticleSystem
    • 五、运行效果
      • 左栏:burst 脉冲发射
      • 右栏:pulse 定时脉冲
    • 六、适用边界与限制条件
    • 七、总结与下篇预告

一、发射器是粒子系统的源头

粒子系统的所有视觉表现都始于 Emitter——它决定了粒子从哪里来、以什么频率出来、出来后往哪飞。如果把 ParticleSystem 比作一个舞台,Emitter 就是演员的入口;入口的大小、位置和开放方式,直接决定了演出的效果。

上一篇示例中展示了连续发射,但实际项目中的发射需求远不止这一种:爆炸效果需要"一次性涌出大量粒子",按钮点击反馈需要"点击后短暂发射",背景粒子需要"持续稳定输出"。这三种需求分别对应 Emitter 的三种发射模式:burst()脉冲、pulse()定时脉冲、emitRate连续发射。

本文的目标是彻底理解这三种模式的行为差异、参数含义和适用场景,让你在面对任何发射需求时都能选择正确的方案。


二、开发环境与版本说明

本文所有代码基于以下环境验证(验证日期:2026-06-08):

  • Qt 版本:6.8.2(最低要求 Qt 6.5,参见 CMakeLists.txt 中qt_standard_project_setup(REQUIRES 6.5)
  • 编译器:MinGW 64-bit
  • 操作系统:Windows 11
  • 构建工具:CMake 3.29

三、原理分析:三种发射模式

3.1 emitRate 连续发射

emitRate是 Emitter 最基础的属性,表示每秒发射的粒子数量。它的行为是:只要enabledtrue且 ParticleSystem 处于running状态,就按照固定频率持续发射粒子。

Emitter { emitRate: 80 // 每秒发射 80 个粒子 lifeSpan: 2000 // 每个粒子存活 2 秒 size: 12 }

稳态粒子数的估算:当发射和消亡达到平衡时,屏幕上的活跃粒子数约为emitRate × lifeSpan / 1000。上面的例子中,稳态粒子数约为80 × 2000 / 1000 = 160个。这个公式在调参时非常有用——如果你想让屏幕上有 500 个粒子,可以设emitRate: 100, lifeSpan: 5000emitRate: 250, lifeSpan: 2000

emitRate为 0 时:Emitter 不会自动发射任何粒子,但仍可通过burst()手动触发。这在"只在交互时发射"的场景中很常见。

3.2 burst(count) 脉冲发射

burst(count)在调用瞬间一次性发射指定数量的粒子,不依赖emitRate。它适合需要"爆发感"的场景:爆炸、点击光效、烟花绽放。

Emitter { id: emitter emitRate: 0 // 默认不发射 lifeSpan: 2000 size: 12 velocity: AngleDirection { angle: 0 angleVariation: 360 // 全方向扩散 magnitude: 100 } } // 用户点击时触发 MouseArea { onClicked: emitter.burst(50) // 一次性发射 50 个粒子 }

burst 的关键特征

  • 瞬时性:所有粒子在同一帧诞生,视觉上是"同时涌出"
  • 不干扰 emitRateburst()emitRate互不影响,可以在连续发射的同时触发脉冲
  • 可重复调用:每次调用都追加新粒子,不会清除之前的粒子

3.3 pulse(duration) 定时脉冲

pulse(duration)在 Emitter 未启用时,将其启用指定毫秒数,到期后自动关闭。它是emitRateburst()之间的折中方案——既有持续性,又有时间限制。注意:pulse()只在 Emitter 当前未启用(enabled: false)时有效,如果 Emitter 已经启用,调用pulse()不会有额外效果。

Emitter { id: emitter emitRate: 200 // 脉冲期间每秒发射 200 个 enabled: false // 默认禁用 lifeSpan: 2000 size: 12 } // 用户点击时触发 MouseArea { onClicked: emitter.pulse(500) // 启用 500ms,期间按 emitRate: 200 发射 }

pulse 的关键特征

  • 渐进性:粒子在duration毫秒内陆续出现,不像burst()那样同时涌出
  • 自动关闭pulse()结束后,Emitter 自动恢复为enabled: false
  • 受 emitRate 影响:脉冲期间的发射量 =emitRate × duration / 1000

pulse()的效果由emitRateduration共同决定。emitRate控制粒子密度,duration控制持续时间。调用pulse(500)时,Emitter 在 500ms 内按emitRate发射,到期后自动禁用。duration太短(< 200ms)效果接近burst(),太长(> 2000ms)就失去了"脉冲"的感觉。一般建议 300-1000ms。

3.4 三种模式对比

维度emitRate 连续burst(count)pulse(duration)
发射方式持续均匀瞬时爆发限时持续
粒子出现节奏陆续出现同时涌出陆续出现
是否受 emitRate 影响
是否自动停止否(除非 disable)是(一次完成)是(duration 到期)
典型场景背景粒子、持续效果爆炸、点击反馈短暂喷射、呼吸效果

用一张决策流程图来总结:

持续不断的粒子

一次性爆发大量粒子

短暂持续发射

你需要什么效果?

emitRate: N
(连续发射)

emitRate: 0 + burst(N)
(脉冲发射)

emitRate: N + pulse(duration)
(定时脉冲)

背景雪花、星空、水面波纹

爆炸、点击光效、烟花绽放

短暂喷射、呼吸灯、触发效果

四、代码实现:Concept_EmitterMethods.qml 逐段解析

项目中Concept_EmitterMethods.qml并排展示了burst()pulse()两种方法的效果对比。页面分为左右两栏,每栏各有一个粒子系统和一个触发按钮。

4.1 左栏:burst 脉冲发射

ParticleSystem { id: ps1 anchors.fill: parent running: root.isCurrentItem ImageParticle { source: "qrc:/images/star.png" color: "#FF6B6B" alpha: 0.9 } Emitter { id: burstEmitter anchors.centerIn: parent width: 1 height: 1 emitRate: 0 lifeSpan: 2000 size: 12 velocity: AngleDirection { angle: 0 angleVariation: 360 magnitude: 100 } } }

emitRate: 0——Emitter 默认不发射任何粒子。只有当用户点击按钮调用burst(50)时才会产生粒子。这是burst()模式的典型写法:把emitRate设为 0,完全由手动触发控制。

width: 1, height: 1——Emitter 的发射区域设为 1×1 像素,近似一个点。配合angleVariation: 360,粒子从中心点向四面八方均匀扩散,形成爆炸般的视觉效果。

触发逻辑

MouseArea { id: burstArea anchors.fill: parent hoverEnabled: true onClicked: burstEmitter.burst(50) }

每次点击调用burst(50),瞬间发射 50 个粒子。由于lifeSpan: 2000,点击后 2 秒内粒子会逐渐消亡。如果在粒子消亡前再次点击,新旧粒子会叠加,形成更密集的效果。

4.2 右栏:pulse 定时脉冲

Emitter { id: pulseEmitter anchors.centerIn: parent width: 1 height: 1 emitRate: 200 enabled: false lifeSpan: 2000 size: 12 velocity: AngleDirection { angle: 0 angleVariation: 360 magnitude: 100 } }

emitRate: 200, enabled: false——与 burst 模式的关键区别:这里emitRate设为 200(脉冲期间每秒发射 200 个),但enabled默认为false(不发射)。pulse(500)会在 500ms 内临时启用 Emitter,期间按emitRate: 200发射,500ms 后自动恢复enabled: false

触发逻辑

MouseArea { onClicked: pulseEmitter.pulse(500) }

pulse(500)意味着每次点击后,Emitter 在 500ms 内发射约200 × 0.5 = 100个粒子。与burst(50)相比,粒子不是同时涌出,而是在半秒内陆续出现,视觉上更柔和。

duration选择 500ms 的理由:太短(如 200ms)效果接近 burst,太长(如 2000ms)就失去了"脉冲"的感觉。500ms 是一个能体现"陆续出现"特性的中间值。

4.3 为什么用两个独立的 ParticleSystem

左右两栏各自拥有独立的ParticleSystemps1ps2),而不是共享一个。这是因为:

  • 粒子系统的坐标是相对于 ParticleSystem 容器的,两个独立系统可以各自在自己的区域内发射
  • 避免两个 Emitter 的粒子混在一起,影响对比效果
  • 更清晰地展示burst()pulse()的行为差异

五、运行效果

运行项目后,点击左侧导航栏的「发射器」进入本示例页面。页面分为左右两栏,并排展示burst()pulse()的效果对比。

左栏:burst 脉冲发射

点击红色圆形按钮触发burst(50)。观察粒子的诞生方式:50 个红色星形粒子在同一帧同时从中心涌出,向四面八方均匀扩散(angleVariation: 360),形成"爆炸"般的瞬间扩散效果。2 秒后(lifeSpan: 2000)粒子逐渐消亡。

验证方式:连续快速点击多次,观察粒子叠加效果。由于burst()每次追加新粒子而不清除旧粒子,多次点击后屏幕上会同时存在多批粒子,密度明显增大。

右栏:pulse 定时脉冲

点击青色圆形按钮触发pulse(500)。观察粒子的诞生方式:与 burst 不同,粒子不是同时涌出,而是在 500ms 内陆续从中心发射出来(emitRate: 200,500ms 内约发射 100 个粒子)。

验证方式:点击后观察粒子的出现节奏。前 500ms 内粒子持续涌出,500ms 后 Emitter 自动关闭(enabled恢复为false),不再有新粒子产生。已发射的粒子按lifeSpan: 2000自然消亡。

burst 与 pulse 的核心区别

两者的差异体现在粒子的诞生方式上:

  • burst:所有粒子在同一帧诞生,视觉上是"同时涌出"
  • pulse:粒子在duration毫秒内陆续诞生,视觉上是"逐渐流出"

六、适用边界与限制条件

burst()emitRate可以同时使用burst()是额外追加粒子,不影响emitRate的连续发射。比如设emitRate: 20作为背景粒子,同时在用户点击时burst(50)追加爆发效果。

pulse()的前置条件pulse()只在 Emitter 当前未启用(enabled: false)时有效。如果 Emitter 已经处于启用状态,调用pulse()不会有额外效果。pulse()结束后,Emitter 自动恢复为enabled: false

maximumEmitted安全阀maximumEmitted限制该 Emitter 的最大活跃粒子数。当活跃粒子数达到上限时,新的发射请求会被忽略。默认值为 -1(无限制)。在burst()大量发射时尤其有用,防止性能崩溃。

lifeSpan的边界值:设为 0 时粒子立即消亡,视觉上看不到任何效果;设为 -1 时粒子永生(不会消亡),粒子数会无限增长直到性能崩溃。

emitRate的性能上限:设为极大值(如 10000)时,瞬间发射大量粒子可能导致帧率骤降。如果需要更密集的效果,优先增大lifeSpan而不是emitRate——增大lifeSpan让粒子存活更久,自然积累更多;增大emitRate则会增加每秒的发射开销。


七、总结与下篇预告

本文讲解了 Emitter 的三种发射模式:

模式核心特征选择依据
emitRate连续持续均匀发射需要不间断的粒子效果
burst(count)瞬时大量发射需要爆发感的一次性效果
pulse(duration)限时持续发射需要短暂但有持续性的效果

选择策略:持续效果用emitRate,交互反馈用burst,定时效果用pulse,混合场景可以组合使用

下一篇将讲解粒子的外观渲染——ImageParticle 的 GPU 批量渲染能力和 ItemParticle 的 QML 组件渲染能力,以及如何在两者之间做出正确的选型。


资源下载:qml_particlesystem —— 包含完整的、可运行的代码

系列目录

  • 上一篇:Qt Quick 粒子系统(二):系统控制与生命周期管理
  • 本文:Qt Quick 粒子系统(三):发射器深度解析
  • 下一篇:Qt Quick 粒子系统(四):渲染器对比与选型指南

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询