SKSpriteNode 从场景中移除后如何停止音频(Swift)?
Posted
技术标签:
【中文标题】SKSpriteNode 从场景中移除后如何停止音频(Swift)?【英文标题】:How to stop an audio of SKSpriteNode after its removed from the scene(Swift)? 【发布时间】:2016-03-28 19:45:45 【问题描述】:这是我的代码:
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()
当我触摸节点(bug)时,它将从场景中移除。在这里,我试图停止播放与该错误相关的音频。但即使从场景中移除节点后,音频也会继续播放。如何在节点从场景中移除后立即停止音频?
【问题讨论】:
顺便说一句,像在闭包中那样使用 self 并永远重复该动作,肯定会使您的场景无法正确取消初始化。要么使用捕获列表(类似于[unowned self]
),要么在实际过渡到下一个场景之前删除该动作。始终检查您的场景的 deinit
是否被正确调用(对您创建的每个自定义类执行此操作)。
@Whirlwind 我对此一无所知.. 但会对其进行研究并将实施。再次感谢您帮助我改进代码。
【参考方案1】:
+ playSoundFileNamed:waitForCompletion: 只是播放声音。您无法控制正在播放的声音(无法暂停、取消暂停、停止等)。有人说您可以为声音动作分配一个键,然后通过移除该键来停止一个动作。到目前为止,这对我来说从来没有用过(在许多 ios 版本上都试过)。
另外,我用操作键尝试这个技巧的最后一个 iOS 版本是 9.1...所以,有机会你可以在 9.3 上尝试...
无论如何,这是来自文档:
使用 SKAction playSoundFileNamed:waitForCompletion: 仅作简称 杂费。使用 AVAudioPlayer 播放长时间运行的背景音乐。这 动作不可逆;反向动作与 原创动作。
所以,它只是播放简短的声音,仅此而已。
作为替代方案,您可以使用SKAudioNode,但它仅适用于 iOS9 及更高版本。
【讨论】:
我使用 SKAudioNode 实现了,现在它工作正常。谢谢!【参考方案2】:这是我如何编码以获得结果。
我在 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()
【讨论】:
以上是关于SKSpriteNode 从场景中移除后如何停止音频(Swift)?的主要内容,如果未能解决你的问题,请参考以下文章
modalViewController 从 superview 中移除后 UIView 消失