来自 CAEmitterLayer 的初始粒子不从 emitterPosition 开始
Initial particles from CAEmitterLayer don't start at emitterPosition
我的目标是制作类似爆炸的动画,其中在短时间内发射出许多粒子。我的问题是,当 CAEmitterLayer 开始发射时,它添加了 "future" 粒子,使动画看起来已经 运行 一段时间了。
如何禁用或解决此问题?当我增加 birthRate 时,我只希望粒子从 emitterPosition 开始出现,而不是在 CAEmitterCell 预计寿命的所有点出现。感谢任何帮助。
#import "EmitterView.h"
@interface EmitterView ()
@property CAEmitterLayer* emitter;
@end
@implementation EmitterView
- (void) awakeFromNib {
[super awakeFromNib];
self.emitter = (CAEmitterLayer*)self.layer;
CAEmitterCell* snowflake = [CAEmitterCell emitterCell];
snowflake.contents = (id)[[UIImage imageNamed: @"snowflake"] CGImage];
snowflake.lifetime = 3;
snowflake.birthRate = 1;
snowflake.velocity = 50;
snowflake.emissionRange = 3.1415;
self.emitter.birthRate = 0;
self.emitter.emitterCells = [NSArray arrayWithObject: snowflake];
self.emitter.emitterPosition = CGPointMake(100, 100);
self.emitter.emitterSize = CGSizeMake(0, 0);
self.emitter.emitterShape = kCAEmitterLayerPoint;
}
+ (Class) layerClass {
return [CAEmitterLayer class];
}
- (void) burst {
self.emitter.birthRate = 10;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
self.emitter.birthRate = 0;
});
}
@end
这种行为实际上随着 iOS 7 的发布而改变,并且显然从那时起就没有恢复。在 iOS 7 之前,它的行为方式与您预期的一样,但要么 Apple 引入了导致这种情况的错误,要么他们选择在不告诉任何人的情况下更改行为。
我在 2013 年 8 月 28 日针对这个确切问题提交了一个错误,该错误已作为同一问题的另一个错误报告的副本而关闭。 Apple 的错误报告者报告说另一个错误仍然存在,这意味着 Apple 还没有解决它,尽管已经解决了一年半多的时间。
我建议向 Apple 提交您自己的错误报告,给他们一个简单的应用程序来演示该行为,也许重新关注它会帮助他们采取一些措施。
编辑:
稍微研究一下这个问题后,我发现解决方案是添加这一行:
self.emitter.beginTime = CACurrentMediaTime();
重要的是要知道 CAEmitterLayer
是 CALayer
的子类,它符合 CAMediaTiming
协议。为什么没有更好地记录整个事实超出了我的范围。
请注意,您可能想从 - (void)burst
方法中调用它,但是如果您在短时间内再次调用它,而之前的粒子仍然存在,您可能会看到一些奇怪的行为因为重置 beginTime
.
我的目标是制作类似爆炸的动画,其中在短时间内发射出许多粒子。我的问题是,当 CAEmitterLayer 开始发射时,它添加了 "future" 粒子,使动画看起来已经 运行 一段时间了。
如何禁用或解决此问题?当我增加 birthRate 时,我只希望粒子从 emitterPosition 开始出现,而不是在 CAEmitterCell 预计寿命的所有点出现。感谢任何帮助。
#import "EmitterView.h"
@interface EmitterView ()
@property CAEmitterLayer* emitter;
@end
@implementation EmitterView
- (void) awakeFromNib {
[super awakeFromNib];
self.emitter = (CAEmitterLayer*)self.layer;
CAEmitterCell* snowflake = [CAEmitterCell emitterCell];
snowflake.contents = (id)[[UIImage imageNamed: @"snowflake"] CGImage];
snowflake.lifetime = 3;
snowflake.birthRate = 1;
snowflake.velocity = 50;
snowflake.emissionRange = 3.1415;
self.emitter.birthRate = 0;
self.emitter.emitterCells = [NSArray arrayWithObject: snowflake];
self.emitter.emitterPosition = CGPointMake(100, 100);
self.emitter.emitterSize = CGSizeMake(0, 0);
self.emitter.emitterShape = kCAEmitterLayerPoint;
}
+ (Class) layerClass {
return [CAEmitterLayer class];
}
- (void) burst {
self.emitter.birthRate = 10;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
self.emitter.birthRate = 0;
});
}
@end
这种行为实际上随着 iOS 7 的发布而改变,并且显然从那时起就没有恢复。在 iOS 7 之前,它的行为方式与您预期的一样,但要么 Apple 引入了导致这种情况的错误,要么他们选择在不告诉任何人的情况下更改行为。
我在 2013 年 8 月 28 日针对这个确切问题提交了一个错误,该错误已作为同一问题的另一个错误报告的副本而关闭。 Apple 的错误报告者报告说另一个错误仍然存在,这意味着 Apple 还没有解决它,尽管已经解决了一年半多的时间。
我建议向 Apple 提交您自己的错误报告,给他们一个简单的应用程序来演示该行为,也许重新关注它会帮助他们采取一些措施。
编辑:
稍微研究一下这个问题后,我发现解决方案是添加这一行:
self.emitter.beginTime = CACurrentMediaTime();
重要的是要知道 CAEmitterLayer
是 CALayer
的子类,它符合 CAMediaTiming
协议。为什么没有更好地记录整个事实超出了我的范围。
请注意,您可能想从 - (void)burst
方法中调用它,但是如果您在短时间内再次调用它,而之前的粒子仍然存在,您可能会看到一些奇怪的行为因为重置 beginTime
.