Как остановить звук SKSpriteNode после его удаления со сцены (Swift)?

Вот мой код:

 override func didMoveToView(view: SKView) {
    /* Setup your scene here */
    let backgroundImage = SKSpriteNode(imageNamed: "Background.jpeg")
    backgroundImage.size = self.frame.size
    backgroundImage.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2)
    backgroundImage.zPosition = 1
    self.addChild(backgroundImage)


    let addBugAction = SKAction.sequence([SKAction.runBlock({
        self.addBugsToScene()
    }), SKAction.waitForDuration(1)])
    self.runAction(SKAction.repeatActionForever(addBugAction))

}

func addBugsToScene() {

    let bug = SKSpriteNode(imageNamed: "Mos2.gif")
    bug.name = "Mosquito"


    //giving random position to and assigning to bugs
    let randomPoint = gettingRandomPosition(bug.size)
    bug.position = CGPoint(x: randomPoint.x, y: randomPoint.y)
    bug.zPosition = 12



    let blockOFaction = SKAction.runBlock({

        let randomMovingPoint = self.gettingRandomPosition(bug.size)

         let action = SKAction.moveTo(CGPoint(x: randomMovingPoint.x, y: randomMovingPoint.y), duration: 2)

        //action.speed = 3.0
        let movePlusSoundAction = SKAction.group([action,SKAction.playSoundFileNamed("MosquitoNoise.wav", waitForCompletion: false)])

        bug.runAction(movePlusSoundAction)

    })
    let waitAction = SKAction.waitForDuration(1)
    bug.runAction(SKAction.repeatActionForever(SKAction.sequence([blockOFaction, waitAction])))


    self.addChild(bug)

}



override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
    {        

   /* Called when a touch begins */

    for touch in touches {
        let location = touch.locationInNode(self)

        let touchedNode = self.nodeAtPoint(location)

        if touchedNode.name == "Mosquito"{

            touchedNode.removeAllActions()

            //touchNode.runAction(SKAction.Stop())

            //removing the bug which is tapped
            touchedNode.removeFromParent()
        }
    }
}

Когда я касаюсь узла (ошибки), он будет удален со сцены. Здесь я пытаюсь остановить воспроизведение звука, связанного с ошибкой. Но звук продолжает воспроизводиться даже после удаления узла со сцены. Как остановить звук, как только нода исчезнет со сцены?


person Pruthvi Hariharan    schedule 28.03.2016    source источник
comment
Между прочим, использование такого self внутри замыкания и постоянное повторение этого действия, безусловно, приведет к тому, что ваша сцена не будет деинитирована должным образом. Либо используйте список захвата (что-то вроде [unowned self] ), либо удалите это действие перед фактическим переходом к следующей сцене. Всегда проверяйте, правильно ли вызывается deinit вашей сцены (делайте это для каждого пользовательского класса, который вы создали).   -  person Whirlwind    schedule 29.03.2016
comment
@Whirlwind Я не знал об этом .. Но изучу это и реализую. Еще раз спасибо, что помогли мне сделать мой код лучше.   -  person Pruthvi Hariharan    schedule 29.03.2016


Ответы (2)


+ playSoundFileNamed:waitForCompletion: просто воспроизводит звук. У вас нет контроля над звуком, который вы воспроизводите (не можете приостановить его, возобновить, остановить и т. д.). Некоторые люди говорят, что вы можете назначить клавишу звуковому действию и остановить действие, удалив клавишу. У меня это никогда не работало (пробовал на многих версиях iOS).

Кроме того, последняя версия iOS, в которой я пробовал этот трюк с клавишей действия, была 9.1 ... Так что есть шанс, и вы можете попробовать это на 9.3 ...

В любом случае, это из документов:

Используйте SKAction playSoundFileNamed:waitForCompletion: только для коротких случаев. Используйте AVAudioPlayer для продолжительной фоновой музыки. Это действие необратимо; обратное действие идентично исходному действию.

Итак, он просто воспроизводит короткий звук и все.

В качестве альтернативы вы можете использовать SKAudioNode, но он доступен только на iOS9 и выше.

person Whirlwind    schedule 28.03.2016
comment
Я реализовал с помощью SKAudioNode, и теперь он работает нормально. Спасибо! - person Pruthvi Hariharan; 29.03.2016

Вот как я закодировал, чтобы получить результат.

Я добавил ниже код в addBugToScene()

let mosquitoNoise = SKAudioNode(fileNamed: "MosquitoNoise.wav")
    mosquitoNoise.autoplayLooped = true
    mosquitoNoise.runAction(SKAction.changeVolumeTo(0.3, duration: 60))
    bug.addChild(mosquitoNoise)

//changes made here
 let movePlusSoundAction = SKAction.group([action,SKAction.runBlock({

            mosquitoNoise.runAction(SKAction.play())
            })])

        bug.runAction(movePlusSoundAction)

    })


 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
   /* Called when a touch begins */

    for touch in touches {
        let location = touch.locationInNode(self)

        let touchedNode = self.nodeAtPoint(location)

        if touchedNode.name == "Mosquito"{

            //removes the SKAudioNode so audio will stop
            touchedNode.removeAllChildren()

            //removing the bug which is tapped
            touchedNode.removeFromParent()

        }
person Pruthvi Hariharan    schedule 28.03.2016