Я работаю над игрой с несколькими монстрами разных видов (один вид = один подкласс SKSpriteNode), пересекающими сцену. Каждому виду дается определенный звук.
Один пример: я могу иметь в определенный момент времени:
- 5 монстров А
- 2 монстра Б
- 0 монстр С
Что бы я хотел в любое время, так это зациклить звук для каждого класса, который является частью сцены (A, B) (а не для каждого спрайта!), и остановить воспроизведение звука для каждого класса, отсутствующего на сцене ( С).
Моей первой идеей было сохранить определенный звук в каждом классе монстров и добавить SKAction к каждому спрайту, который будет воспроизводить в цикле звук своего класса. Но это будет воспроизводить столько звуков, сколько спрайтов на сцене, и это не соответствует моим ожиданиям.
Есть ли у вас идея о том, какой подход лучше всего использовать для этого? Есть ли возможность реализовать своего рода наблюдателя, который мог бы уведомлять, когда экземпляр класса находится на сцене, а когда нет?
Большое спасибо за вашу помощь !
Ответ 1 · рейтинг 1 · Simone Pistecchia
Как сказал @Knight0fDragon, "SKAction не предназначен для воспроизведения зацикленной музыки".
Может быть, вы можете сделать: (я не проверял, сейчас я на машине с Windows)
Class MonsterA : SKSpriteNode {
static var monsterAInScene = Set<Monster>()
static let audioAction: SKAction = SKAction.playSoundFileNamed("MonsterA-audio") //Change to AVAudio for loop
static let audioNode: SKNode()
init (scene:SKScene) {
//Your init
if let MonsterA.monsterAInScene.count == 0 {
//play audio
scene.addChild(MonsterA.audioNode)
MonsterA.playAudio()
}
MonsterA.monsterAInScene.insert(self)
}
static func playAudio() {
//Play audio code
if MonsterA.audioNode.actionFroKey("audio") != nil {return}
MonsterA.audioNode.runaction(MonsterA.audioAction, forKey "audio")
}
override removeFromParent() {
MonsterA.monsterAInScene.remove(self)
if let MonsterA.monsterAInScene.count == 0 {
//stop audio code
MonsterA.audioNode.removeActionWithKey("audio")
MonsterA.audioNode.removeFromParent()
}
super.removeFromParent()
}
}
@Knight0fDragon и @Alessandro Ornano более опытны, чем я, они могут подсказать, как лучше поступить.
Ответ 2 · рейтинг 1 · Laurent Maquet
Я, наконец, принял SKAudioNode, как посоветовал KnightOfDragon.
В начале класса GameScene я добавил наблюдателя для проверки фактического количества монстров каждого вида (здесь с типом A):
var monsterASound = SKAudioNode()
var currentNumberOfMonsterA = 0 {
didSet {
if currentNumberOfMonsterA > 0 {
monsterASound.runAction(SKAction.play())
} else{
monsterASound.runAction(SKAction.stop())
}
}
}
currentNumberOfMonsterA обновляется каждый раз, когда я добавляю/удаляю монстра
//Add a monster A
self.currentNumberOfMonsterA += 1
//Removing a monster A
self.currentNumberOfMonsterA -= 1
//Destroying a monster A
self.currentNumberOfMonsterA -= 1
Затем в didMoveToView я добавил в сцену SKAudioNode.
self.monsterASound = SKAudioNode(URL: NSBundle.mainBundle().URLForResource("monsterA", withExtension: "wav")!)
self.monsterASound.runAction(SKAction.stop())
addChild(helicoSound)