【问题标题】:Playing multiple sounds at contact - Xcode Scene Kit在接触时播放多种声音 - Xcode Scene Kit
【发布时间】:2020-05-28 15:20:40
【问题描述】:

这是一个具有挑战性的问题,我还没有找到答案。这就是为什么我最终创建了一个帐户,停止潜伏并成为社区的一部分:

我正在编写一个游戏,当你摇晃手机时,5 个 SCNNode(带有骰子纹理的盒子)会在一个由 2 个 SCNNode(盒子和地板)形成的框架内反弹。它模拟扑克骰子游戏。

我编写了一个接触代表,每次一个骰子碰到另一个骰子或盒子时,我都会播放一个声音,但只有第一个骰子接触任何物体,一旦脉冲开始,将是播放声音的人

每次任何骰子相互接触、地板或框架接触时,我都无法同时播放相同的声音。当只能使用 nodeA 和 nodeB 进行编码时,我无法获得令人满意的“声音级联”。许多接触同时发生,但只有一个播放声音。

这是我的代码的样子:

extension GameViewController : SCNPhysicsContactDelegate {
func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {

    if (contact.nodeA.physicsBody?.categoryBitMask == BodyType.die.rawValue && contact.nodeB.physicsBody?.categoryBitMask == BodyType.die.rawValue){

        do{
            audioPlayer?.play()
        }catch{
        }
    }else if (contact.nodeB.physicsBody?.categoryBitMask == BodyType.box.rawValue && contact.nodeA.physicsBody?.categoryBitMask == BodyType.die.rawValue){

        do{
            audioPlayer?.play()
        }catch{
        }

}}}

AVaudioPlayer 在 ViewLoad 中准备好。我没有费心填写 catch 实例。

这里我有一个 enum 类别位掩码,因此我可以测试联系人:

enum BodyType:Int {

case die = 1
case box = 2
case floor = 4

}

我如何在任何骰子碰到另一个骰子、地板或框架时播放声音?

非常感谢!

【问题讨论】:

    标签: swift xcode scenekit avaudioplayer contacts


    【解决方案1】:

    我的解决方法有点不同,但也许这会有所帮助:

    意见各不相同,但我发现 SK 声音在这种情况下效果更好,所以我添加了一个 SKOverlay 并将其用于声音。添加了几个声音节点来分散使用,因为我同时播放了 100 个对象。创建了一个类似的声音类:

    var explosions = [gameTypes: SKAction]()
    let vAction = SKAction.playSoundFileName(vName, waitForCompletion: False)
    audioNodeAction.run(explosions[soundType]
    

    预加载动作/声音,然后播放下面的声音,如 (enemyMissileHit)

    在联系人中,我使用了节点名称,但有几种方法:

    guard let nodeNameA = contact.nodeA.name else { return }
    guard let nodeNameB = contact.nodeB.name else { return }
    
    if(nodeNameA.prefix(5) == "Explo" && nodeNameB.prefix(5) == "Missi")
    {
     gameControl.enemyMissileHit(vIndex: Int(nodeNameB.suffix(4))!)
    }
    if(nodeNameA.prefix(5) == "Missi" && nodeNameB.prefix(5) == "Explo")
    {
     gameControl.enemyMissileHit(vIndex: Int(nodeNameA.suffix(4))!)
    }
    if(nodeNameA.prefix(5) == "Explo" && nodeNameB.prefix(5) == "Hive ")
    {
     gameControl.enemyHiveHit(vIndex: Int(nodeNameB.suffix(4))!)
    }
    if(nodeNameA.prefix(5) == "Hive " && nodeNameB.prefix(5) == "Explo")
    {
     gameControl.enemyHiveHit(vIndex: Int(nodeNameA.suffix(4))!)
    }
    

    对于您的,只需命名您的所有节点(例如 Floor),希望对您有所帮助。我必须输入这个,所以请原谅语法错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-20
      • 1970-01-01
      相关资源
      最近更新 更多