ios - 在 spritekit swift 中触摸节点时不播放声音

标签 ios swift audio sprite-kit

我想在点击节点时发出声音。 目前的代码是:

    let sndButtonClick = SKAction.playSoundFileNamed("button_click.wav", waitForCompletion: false)

从触摸开始

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


    for touches: AnyObject in touches {


        let location = touches.locationInNode(self)
        if playButton.containsPoint(location) {
           playButton.runAction(sndButtonClick)
            playButton.removeFromParent()

            let nextScene = GamePlayMode(size: self.scene!.size)
            nextScene.scaleMode = self.scaleMode
            self.view?.presentScene(nextScene)
        }
}

我在游戏模式中为两个节点的碰撞做了完全相同的事情并且它有效但在主菜单中它不起作用!

我试过了

self.runAction(sndButtonClick)

然后

playbutton.runAction(sndButtonClick)

都没有用

最佳答案

为什么在按钮上运行声音操作不起作用?

这是来自文档:

An SKAction object is an action that is executed by a node in the scene (SKScene)...When the scene processes its nodes, actions associated with those nodes are evaluated.

表示节点的操作只有在节点被添加到场景中时才会运行。所以这没有效果:

playButton.runAction(sndButtonClick)
playButton.removeFromParent()

因为您已经从场景中删除了按钮,并且在应该执行操作时它不会出现在下一帧中。这就是 runAction 方法的工作原理:

Adds an action to the list of actions executed by the node...The new action is processed the next time the scene’s animation loop is processed.

另外,因为你是立即调用presentScene 无论如何不会有下一帧,所以即使你删除了removeFromParent语句,声音也不会工作,因为没有下一帧。

为什么在场景中运行声音 Action 不起作用?

self.runAction(sndButtonClick) 将不起作用,因为您正在立即进行转换,而无需等待将执行排队操作的下一帧(如上所述)。

问题的解决方案

要在过渡前播放声音,您必须等待下一帧,您可以这样做:

runAction(sndButtonClick, completion: {
   self.view?.presentScene(nextScene)
})

let block = SKAction.runBlock({
   self.view?.presentScene(nextScene)
})

runAction(SKAction.sequence([sndButtonClick, block]))

防止泄漏:

考虑在 block 内使用捕获列表来捕获 self 以避免在需要时可能出现的强引用循环,如下所示:

let block = SKAction.runBlock({
   [unowned self] in
   //use self here
})

在您的这种特殊情况下,没有捕获列表应该是安全的,因为场景没有对 block 的强引用。只有block对场景有强引用,但是block执行后,因为没有东西保留它(没有强引用),所以会被释放,这样场景才能正确释放。但是,如果该 block 被声明为一个属性,或者执行该 block 的操作正在无限运行(使用 repeateActionForever 方法重复某个序列),那么您肯定会发生泄漏。

您应该始终覆盖场景的 deinit 以查看发生了什么(如果未调用它,则保留场景并导致泄漏)。

关于ios - 在 spritekit swift 中触摸节点时不播放声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35716994/

相关文章:

ios - UISearchController 在结构中搜索结构数组

ios - 如何使用 Moya pod 为请求设置超时?

ios - Google 自动完成地点国家/地区过滤器在 iOS 中不起作用

javascript - HTML 中的多个音频文件,如果单击两个,较旧的文件应停止播放

直接从 appDelegate 切换选项卡时 iOS NSURLConnection 失败

ios - View Controller only 协议(protocol)无权访问 View Controller 属性

ios - 在登录页面全屏播放视频

javascript - 向导航按钮添加声音的最佳方式?

android - 用于在android中缓冲编码音频的数据结构

ios - 根据动态本地内容确定 UIWebView 高度,在可变高度 TableViewCell 内