重复触发 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.0yourPlayerInstance.volume=1.0。这为我解决了帧故障/丢帧问题——完美的 60 fps 而不是降至 ~40 fps。

【讨论】:

以上是关于重复触发 AVAudioPlayer 时,大量 fps 下降(Sprite Kit)的主要内容,如果未能解决你的问题,请参考以下文章

给定现有路径的 AVAudioPlayer 大量加载音频

AVAudioPlayer 可以在预定义的时间间隔触发事件吗?

触发 AVAudioPlayer 以停止所有声音并播放选定的声音,除非单击播放(选定)按钮

如何在底部面板中存储当前音频信息(AVAudioPlayer,Swift)[重复]

当应用程序在后台时启动 AVAudioPlayer

AVAudioPlayer Swift 3不播放声音[重复]