重复触发 AVAudioPlayer 时,大量 fps 下降(Sprite Kit)
Posted
技术标签:
【中文标题】重复触发 AVAudioPlayer 时,大量 fps 下降(Sprite Kit)【英文标题】:Massive fps drops when AVAudioPlayer ist triggered repeatedly (Sprite Kit) 【发布时间】:2014-09-03 14:10:29 【问题描述】:我正在使用 Sprite Kit 创建一个 ios 游戏,您可以在其中发射水枪。只要水枪开火,就会播放一个斜线声。由于我实现了这个功能,当使用 touches-began-method 反复触发音效时,我遇到了大量的 fps 问题。
有没有办法解决这个问题?
@property (nonatomic) AVAudioPlayer *splashSound;
-(id)initWithSize:(CGSize)size
NSError *error3;
NSURL *splashURL = [[NSBundle mainBundle] URLForResource:@"splash" withExtension:@"caf"];
self.splashSound = [[AVAudioPlayer alloc]initWithContentsOfURL:splashURL error:&error3];
self.splashSound.numberOfLoops = 1;
[self.splashSound prepareToPlay];
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
/* Called when a touch begins */
startGamePlay = YES;
if (self.waterCapacity != 0)
waterSprayed = YES;
[self.splashSound play]; // sound starts when screen is touched
[self.currentWasser sprayWater];
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
[self.currentWasser removeActionForKey:@"water"];
[self.splashSound pause]; // sound is paused when touches ended
waterSprayed = NO;
【问题讨论】:
为什么音效应该一直播放的时候循环数是1?如果它是一个长音频文件,您应该将其更改为一个小文件(1-5 秒)并简单地循环播放。 PS:如果你不使用错误对象,你可以在 init 方法中传入 error:nil 。 这个在真机上测试过吗?模拟器很糟糕。 感谢您的回复。不幸的是,这种变化没有任何区别。我想我会使用 UILongPressGestureRecognizer 以便在触摸屏幕 1 秒后播放声音文件。我想我可以通过这种方式防止低帧率 【参考方案1】:使用 UILongPressGestureRecognizer 修复它:完美运行。好开心!
- (void)didMoveToView:(SKView *)view
UILongPressGestureRecognizer *longGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(delayedSplashSound:)];
longGesture.minimumPressDuration = 0.15;
[view addGestureRecognizer:longGesture];
- (void)delayedSplashSound:(UITapGestureRecognizer *)recognizer
if (recognizer.state == UIGestureRecognizerStateBegan)
[self.splashSound play];
else if (recognizer.state == UIGestureRecognizerStateEnded)
[self.splashSound pause];
[self.currentWater removeActionForKey:@"water"];
waterSprayed = NO;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
startGamePlay = YES;
if (self.waterCapacity != 0)
waterSprayed = YES;
[self.currentWater sprayWater];
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
[self.currentWater removeActionForKey:@"water"];
waterSprayed = NO;
【讨论】:
【参考方案2】:在无限循环中使用 AVAudioPlayer.play()
和 AVAudioPlayer.stop()
时,我还有另一个解决掉帧问题的方法。无需调用play()
和stop()
,只需调用一次play()
并设置yourPlayerInstance.volume=0.0
和yourPlayerInstance.volume=1.0
。这为我解决了帧故障/丢帧问题——完美的 60 fps 而不是降至 ~40 fps。
【讨论】:
以上是关于重复触发 AVAudioPlayer 时,大量 fps 下降(Sprite Kit)的主要内容,如果未能解决你的问题,请参考以下文章
AVAudioPlayer 可以在预定义的时间间隔触发事件吗?
触发 AVAudioPlayer 以停止所有声音并播放选定的声音,除非单击播放(选定)按钮