粒子发射器带来的乐趣

我喜欢HackingWithSwift网站和YouTube视频。 我认为保罗·哈德森(Paul Hudson)在用易于理解的术语和清晰示例来解释概念方面做得非常出色。 我一直想了解有关iOS动画的更多信息,以及寻找向iOS应用添加一些简单功能的方法。 斯威夫特问世期间 系列文章中有一篇关于Core Animation的文章,涉及绘制漂亮的白雪皑皑的背景。 在那篇文章中,我发现最有趣的是使用粒子发射器使雪花飘落。 我曾经在游戏中看到过粒子发射器,例如用于产生爆炸或魔术效果的游戏,但在非SpriteKit iOS应用中却没有。 这让我想知道可以使用粒子发射器创建什么其他效果。

粒子发射器是一种在应用程序屏幕上增加一点天赋的好方法,而无需在创建动画上进行大量投资。 在开始使用粒子发射器时,我首先创建了与Swift来临类似的降雪效果 通过将CAEmitterLayerCAEmitterCell与简单的渐变结合CAEmitterLayer ,可以创建一个非常简单的效果。

粒子发射器的代码相当简单,并从Swift的Advent中得到了充分利用 要注意的主要元素是CAEmitterLayerCAEmitterCell 。 让我们快速依次查看每个元素。 Apple文档将CAEmitterLayer描述为:

发射,设置动画和渲染粒子系统的层。

本质上,该层负责生成由CAEmitterCell定义的粒子(即雪)。 发射极层的重要属性是shapepositionsizemode 。 默认形状是point ,这意味着所有粒子都将从特定点发射。 还有其他几种形状选项,例如linecirclerectangle甚至cuboid 。 发射器形状的大小和位置属性将影响其输出以及模式设置。 Apple文档将发射器模式描述为:

一个字符串,定义如何相对于发射形状创建粒子。 当前选项是“点”,“轮廓”,“表面”和“体积”(默认)。

在我们的粒子视图中, CAEmitterLayer被用作基础层。 但是,生成粒子的实际工作是由CAEmitterCell类完成的。 适用于CAEmitterCell状态的Apple文档:

CAEmitterCell类表示由CAEmitterLayer对象发射的粒子的一种来源。 发射器单元定义了发射粒子的方向和属性。 发射器单元可以具有一个子单元阵列,该单元可以使粒子本身发射粒子。

可以将多种运动和时间属性应用于单元格。 我们将在后面的部分中进一步介绍这些内容。 降雪发射器中使用的主要参数是birthRatelifetimebirthRatebirthRate 。 这是文档关于每个文档的陈述:

birthRate :每秒创建的发射对象的数量
life :单元的寿命,以秒为单位
missionLongitud e:发射角的纵向方向
missionRange :以弧度为单位的角度,定义围绕发射角度的圆锥

birthRatebirthRatebirthRate解释,每秒生成的速率以及每个粒子存在的时间。 另一方面,排放值则不同。 根据分配给CAEmitterLayer的发射器形状和发射器模式,这些值会产生不同的影响。

发射经度 -发射角的方向(以弧度为单位),相对于发射形状的自然方向角。 请注意,这里的纬度通常是所谓的纬度,天顶或phi,即与z轴的夹角。 同样,经度是xy平面中与x轴的夹角,通常称为方位角或theta。 两个值均默认为零,这表示相对于发射形状的方向没有变化。

发射范围 —围绕发射角定义圆锥的角度(以弧度为单位)。 发射的对象均匀分布在整个圆锥体上。 默认为零。

对于降雪效果,我们使用了线形的发射器形状,因为我们希望降雪从屏幕顶部落下。 position属性是一个CGPoint ,对于线条的位置,我们将x坐标设置为视图边界的midX值,并将midX值设置为零。 size属性是一个CGSize ,我们将其设置为等于视图边界的宽度,且高度为1。这将创建一个降雪效果,该效果起源于视图的顶部并跨越了整个长度。

零的emissionLongitude经度将导致粒子从该线向上上升,从而产生起泡状效果。 因为我们要降雪,所以我们需要将emissionLongitude经度旋转180度或pi,因为此属性采用弧度值。 emissionRange值使颗粒自然飘落的雪花。 例如,如果将其设置为零(默认值),则粒子将沿直线下落,并且在行进时方向不变。 尽管这是一个有趣的效果,但不是很自然。 将其设置为pi表示180度的角度,而2 * pi将导致粒子在所有方向上分散。 我们想要的是一个较小的发射锥,例如20或30度,pi / 8约为22度。 这样可以产生足够的变化,使降雪看起来更加自然。 emitterModeemitterShapeemissionLongitudeemissionRange都组合在一起以影响所产生的效果。 您会发现自己将这些值调整了几个小时才能获得理想的效果。

我真正想要创建的是更复杂的效果,例如烟火。 如果您使用过SpriteKit,则知道可以创建一个SpriteKit Emitter File来产生火种,并修改这些值以产生爆炸或引擎火焰,或产生许多其他效果。 您可以在任何Xcode项目中创建粒子效果,方法是选择文件->新建->文件-> SpriteKit粒子文件

有几种选择,例如着火,冒烟和下雨。 每个配置都不相同。 您可以交互地调整参数,以查看更改对粒子行为的影响。 创建的粒子文件的类型为SKEmitterNode ,它具有某些属性(例如, SKEmitterNode ,这些属性在CAEmitterCell上不可用。 调整效果时要记住的一点是SpriteKit使用的坐标系类似于OS X,原点位于左下角。

创建烟火效果将比我原本打算花费更多的时间和精力。 最初,我从类似于雪的基本发射器效果开始。 一种粒子发射器,它使用类似于t火花的图像在球体中生成粒子。 通过更改形状和发射器模式,您可以创建一些有趣而古朴的效果,例如一圈火花。 但是,这些都不会产生看起来像真正的烟火的效果。

在这一点上,我很困惑,无法找到一种生成真实外观的消防作品的方法。 我开始在网上搜索粒子发射器的示例。 我终于碰到了一些用于创建烟花的苹果示例代码。 该代码来自2016年,并且是针对MacOS编写的,这意味着它将需要转换为Swift,但这正是我所追求的。 作为一个很好的奖励,该示例提供了一个不错的GUI来调整许多CAEmitterLayerCAEmitterCell值,以便您可以看到更改这些值的影响。

制作烟火并不像我想象的那么容易,事实上,事实证明,我们需要使用一些先进的技术来完成这项壮举。 如果要创建更有趣的效果,则需要组合CAEmitterCell 。 烟花由几部分组成:耀斑或尾巴,是一团掉落的颗粒; 爆炸或实际的烟花将是一个单独的发射器单元,最后是一个闪光效果,代表了我们在大型烟花爆炸中通常看到的闪光。 将所有这些CAEmitterCell将为我们带来不错的烟火效果。 然后,我们将它们添加到另一个发射器单元中,该单元将代表发射到天空中的火箭。

完成此操作的方法是创建多个CAEmitterCell单元,并将它们分配给另一个单元的emitterCells属性。 没错,发射器单元可以有发射器单元。 这意味着您可以从单个发射器单元产生多种效果。 在单元格中使用单元格还有一些其他的挑战和警告,您需要了解这些挑战和警告,有关这些信息,Apple的emitterCells属性(强调我的文档)中提到了这些警告和警告:

指定时,该单元发射的每个粒子将充当该单元的每个子单元的发射器。 发射点是当前粒子的位置 ,发射角度是相对于粒子的当前方向的。

根据发射单元的要求以及在烟花的特定阶段,每个发射器单元将具有不同的属性。 我们需要介绍这些单元中使用的一些其他属性。 duration属性“ 以秒为单位指定动画的基本持续时间。 ”当合并单元时,这一点很重要,否则您最终可能会在实际的烟花动画之前产生逐渐消失的耀斑。 velocity影响粒子行进时的速度,而yAcceleration本质上是重力。 velocity越大,粒子传播得越快,越远。 这基于重力而增加或减少。 如果重力降低(负yAcceleration ),则对velocity的影响将增加。 正值表示增加的重力会减慢粒子的速度并将其向下拖动。 我们将使用的其他一些属性是scalerange属性。 许多属性都有范围(例如, velocity, scaleemissionRange )。 范围值确定给定属性可以从设置值变化的“ 平均值 ”。 因此,比例范围为1.0意味着将比例值设置为5.0可以在4.0-6.0之间。 范围为我们提供了一种动态更改粒子大小及其移动速度的方法。 让我们看一下烟火粒子发射器代码。

注意 :如先前在SpriteKit中提到的,坐标系是翻转的,忘记了这会在使用发射器(尤其是yAcceleration)时在UIKit中使您发疯。

更改粒子的图像可以提供不同而不同的效果。 如果需要,您可以在每个阶段使用不同的图像,例如,爆炸使用星形图像,而闪闪发光使用菱形。 我只选择对所有发射器使用相同的t形火花图像。

该项目的源代码位于github上,其中有这三种效果的有效示例。

资料来源
迅捷黑客
将发射器层与用户触摸相结合
iOS 5开发人员手册
iOS Auto Layout神秘化
度/弧度圆
苹果示例代码
应用程序图标— Artem White
生日蛋糕图片
西雅图图片