Воспроизвести звуковой цикл, пока хотя бы один спрайт этого класса находится на сцене.

Я работаю над игрой с несколькими монстрами разных видов (один вид = один подкласс SKSpriteNode), пересекающими сцену. Каждому виду дается определенный звук.

Один пример: я могу иметь в определенный момент времени:

  • 5 монстров А
  • 2 монстра Б
  • 0 монстр С

Что бы я хотел в любое время, так это зациклить звук для каждого класса, который является частью сцены (A, B) (а не для каждого спрайта!), и остановить воспроизведение звука для каждого класса, отсутствующего на сцене ( С).

Моей первой идеей было сохранить определенный звук в каждом классе монстров и добавить SKAction к каждому спрайту, который будет воспроизводить в цикле звук своего класса. Но это будет воспроизводить столько звуков, сколько спрайтов на сцене, и это не соответствует моим ожиданиям.

Есть ли у вас идея о том, какой подход лучше всего использовать для этого? Есть ли возможность реализовать своего рода наблюдателя, который мог бы уведомлять, когда экземпляр класса находится на сцене, а когда нет?

Большое спасибо за вашу помощь !


person Laurent Maquet    schedule 01.09.2016    source источник
comment
Ваш звук SKAction? Если да, для каждого класса используйте 'static func = ...' для использования один раз   -  person Simone Pistecchia    schedule 01.09.2016
comment
Спасибо, Симона. да, это SKAction. С вашим предложением, даже если я использую функцию один раз, мне нужно знать, когда запускать звуковой цикл, а когда его останавливать (по наличию или отсутствию хотя бы экземпляра класса).   -  person Laurent Maquet    schedule 01.09.2016
comment
@LaurentMaquet Не могли бы вы указать, какова минимальная совместимость вашего проекта с iOS? Это iOS 8.x?   -  person Alessandro Ornano    schedule 01.09.2016
comment
Я бы даже не стал использовать статическую функцию, создать родительский узел, содержащий типы монстров, и воспроизвести звук с родительского узла.   -  person Knight0fDragon    schedule 01.09.2016
comment
Конечно, SKAction не предназначен для воспроизведения зацикленной музыки, и вам следует использовать AVFoundation или если ›= 9.0 SKAudioNode   -  person Knight0fDragon    schedule 01.09.2016
comment
С SKAudioNode я обнаружил много сбоев   -  person Simone Pistecchia    schedule 01.09.2016
comment
@SimonePistecchia У меня еще никогда не было сбоев с SKAudioNode   -  person Knight0fDragon    schedule 01.09.2016
comment
@Alessandro Моя цель развертывания - 9.0   -  person Laurent Maquet    schedule 01.09.2016


Ответы (2)


Как сказал @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 более опытны, чем я, они могут подсказать, как лучше поступить.

person Simone Pistecchia    schedule 01.09.2016
comment
У нас был разговор с Knight0fDragon об аудио. Вы можете найти его здесь: stackoverflow.com/a/38408288/1894067. ИМХО AVAudioFoundation все еще может многое дать играм, но если ваш проект начинается с версии iOS 9.x, я предпочитаю использовать, по согласованию с Knight0fDragon, SKAudioNode. Но я никогда не пробовал зацикленную музыку через SKAction. - person Alessandro Ornano; 01.09.2016
comment
Я создал собственный класс SKAudio, SKAudioNode по-прежнему дает сбой, когда приложение переходит из неактивного состояния в активное, пауза в SKAudioNode, похоже, имеет ошибку. ссылка - person Simone Pistecchia; 01.09.2016
comment
@SimonePistecchia АААА, это твоя проблема? Пауза не работает с iOS 9 для SKNode (по какой-то причине она изменяет состояние паузы всех своих дочерних элементов). Что вам нужно сделать, это расширить все возможные подклассы SKNode, затем переопределить паузу, запомнить состояние паузы дочерних элементов , измените паузу, затем сбросьте состояние паузы дочерних элементов. Это настоящая боль для реализации. Кроме того, вы не можете использовать SKNode, вам нужно будет подклассировать специальную версию этого для обработки паузы (если кто-то не может сказать мне, как переопределить паузу на SKNode) - person Knight0fDragon; 01.09.2016
comment
@All Спасибо за ваше время и ваши идеи. Я работаю над этим сейчас! - person Laurent Maquet; 01.09.2016
comment
@Knight0fDragon Спасибо за подсказку. Но на данный момент лучше использовать AVAudio вместо подкласса всех моих узлов, верно? - person Simone Pistecchia; 02.09.2016
comment
Нет, вы должны писать расширения (только для sknode нужен подкласс) для всего, иначе вы никогда не сможете использовать паузу на каком-либо SKNode. - person Knight0fDragon; 02.09.2016

Я, наконец, принял 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)
person Laurent Maquet    schedule 02.09.2016