Search code examples
sprite-kitavaudioplayerframe-rate

Massive fps drops when AVAudioPlayer ist triggered repeatedly (Sprite Kit)


I am creating an iOS-Game in Sprite Kit in which you can fire a water gun. As long as the water gun is fired, a slash-sound is played. Since I implemented this feature, I have massive fps-problems when the sound effect ist triggered repeatedly with the touches-began-method.

Is there any possibility to fix that issue?

@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;
}

Solution

  • Fixed it with an UILongPressGestureRecognizer: works perfectly. So happy!

    - (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;
    }