问题描述
我的目标是制作一个爆炸般的动画,在短时间内发射出许多粒子.我的问题是CAEmitterLayer在开始发光时会添加未来"粒子,以使其看起来好像动画已经运行了一段时间.
My goal is to make an explosion-like animation where many particles are emitted in a short duration. My problem is that CAEmitterLayer, when it begins emitting, adds "future" particles to make it looks like the animation has been running for a while.
如何禁用或解决此问题?当我增加birthRate时,我只希望粒子从发射器位置开始出现,而不是在CAEmitterCell的预计寿命中的所有点上出现.感谢您的帮助.
How can I disable or workaround this? When I increase the birthRate, I only want particles to start appearing from the emitterPosition, and not at all points along the CAEmitterCell's projected lifetime. Any help is appreciated.
#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引入了一个导致此问题的错误,或者他们选择在不告知任何人的情况下更改了行为.
This behavior actually changed with the release of iOS 7 and apparently hasn't gone back since then. It used to behave the way you would expect back before iOS 7, but either Apple introduced a bug that caused this, or they chose to change the behavior without telling anybody.
我在2013年8月28日针对此确切问题提交了一个错误,该错误已作为同一问题的另一个错误报告的副本关闭.苹果的错误报告者报告说,另一个错误仍在打开中,这意味着尽管有一年半的时间了,苹果仍未解决.
I filed a bug for this exact issue on August 28, 2013, which was closed as a duplicate of another bug report for the same issue. Apple's bug reporter is reporting that the other bug is still open, which means Apple hasn't addressed it yet, despite more than a year and a half to take care of it.
我建议向Apple提交您自己的错误报告,为他们提供一个简单的应用程序来演示其行为,并且也许重新引起人们的关注将有助于他们采取一些措施.
I recommend filing your own bug report with Apple, giving them a simple app that demonstrates the behavior, and maybe getting some renewed attention to it will help get them to do something about it.
在对问题进行了一点研究之后,我发现解决方案是添加以下行:
After researching the issue a little, I found out that the solution is to add this line:
self.emitter.beginTime = CACurrentMediaTime();
重要的是要知道CAEmitterLayer
是CALayer
的子类,它符合CAMediaTiming
协议.为什么没有更好地记录整个事实,这超出了我的范围.
It's important to know that CAEmitterLayer
is a subclass of CALayer
, which conforms to the CAMediaTiming
protocol. Why this whole fact isn't better documented is beyond me.
请注意,您可能想从- (void)burst
方法调用此函数,但是如果在很短的时间内再次调用它,而先前的粒子仍在附近,则由于重置了beginTime
.
Note that you probably want to call this from your - (void)burst
method, but that if you call it again within a short period of time, while previous particles are still around, you might possibly see some odd behavior because of resetting the beginTime
.
这篇关于来自CAEmitterLayer的初始粒子不是从发射器位置开始的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!