【问题标题】:Sprite Kit, can't find a mistakeSprite Kit,找不到错误
【发布时间】:2016-10-11 09:52:05
【问题描述】:

请帮我找出错误。

我需要每个打击垫从阵列中播放自己的声音,但只有打击垫 13、14、15 可以。同时我在每个焊盘上放了一个带有节点名称的标签,说明该节点有一个名称,所以看起来问题不在名称中,我无法理解它是什么。 如果您对改进此代码还有其他要说的,请随时说,我是新手,很高兴听到。

我做错了什么?

谢谢

PS:我想说,我在 sprite kit 上这样做只是为了挑战。

import SpriteKit
import GameplayKit
import AVFoundation

class GameScene: SKScene {

var i = 1
let sounds  = ["Kick", "Clap","Hat","OpHat","Snare","Cow","Crash","Snap","Chant","Tom","11","12","13","14","15"]

override func didMove(to view: SKView) {

    do {

        for sound in sounds {

            let player = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: Bundle.main.path(forResource: sound, ofType: "wav")!) as URL)
            player.prepareToPlay()

        }


    } catch {

    }

    var frameHightMulti = CGFloat(0)

    self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)

    let tittleLabel = SKLabelNode(text: "Let the music play")
    tittleLabel.fontSize = 50
    tittleLabel.fontName = "Helvetica Nue"
    tittleLabel.fontColor = UIColor.white
    tittleLabel.position = CGPoint(x: 0, y: 600)
    addChild(tittleLabel)

    for _ in 1...5 {

        var frameWidthMulti = CGFloat(0)

        for _ in 1...3 {

            let pad = SKSpriteNode(color: UIColor.cyan, size: CGSize(width: 220, height: 220))
            pad.physicsBody = SKPhysicsBody(rectangleOf: pad.frame.size)
            pad.position = CGPoint(x: -240 + frameWidthMulti, y: -500 + frameHightMulti)
            pad.name = sounds[i-1]


            let nameLabel = SKLabelNode(text: pad.name)
            nameLabel.fontSize = 50
            nameLabel.fontName = "Helvetica Nue"
            nameLabel.fontColor = UIColor.black
            nameLabel.position = pad.position

            addChild(pad)

            addChild(nameLabel)

            frameWidthMulti += pad.size.width + 20
            i += 1
        }

        frameHightMulti +=  240


    }



}



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

    let touchLocation = touches.first?.location(in: self)

    if let body = self.physicsWorld.body(at: touchLocation!){

        if let z = body.node?.name {

            switch z {

            case "15":
                self.run(SKAction.playSoundFileNamed("15", waitForCompletion: false))
                print(z)
            case "14":
                self.run(SKAction.playSoundFileNamed("14", waitForCompletion: false))
                print(z)
            case "13":
                self.run(SKAction.playSoundFileNamed("13", waitForCompletion: false))
                print(z)
            case "12":
                self.run(SKAction.playSoundFileNamed("12", waitForCompletion: false))
                print(z)
            case "11":
                self.run(SKAction.playSoundFileNamed("11", waitForCompletion: false))
                print(z)
            case "Tom":
                self.run(SKAction.playSoundFileNamed("Tom", waitForCompletion: false))
                print(z)
            case "Crash":
                self.run(SKAction.playSoundFileNamed("Crash", waitForCompletion: false))
                print(z)
            case "Snap":
                self.run(SKAction.playSoundFileNamed("Snap", waitForCompletion: false))
                print(z)
            case "Chant":
                self.run(SKAction.playSoundFileNamed("Chant", waitForCompletion: false))
                print(z)
            case "Cow":
                self.run(SKAction.playSoundFileNamed("Cow", waitForCompletion: false))
                print(z)
            case "Snare":
                self.run(SKAction.playSoundFileNamed("Snare", waitForCompletion: false))
                print(z)
            case "OpHat":
                self.run(SKAction.playSoundFileNamed("OpHat", waitForCompletion: false))
                print(z)
            case "Hat":
                self.run(SKAction.playSoundFileNamed("Hat", waitForCompletion: false))
                print(z)
            case "Clap":
                self.run(SKAction.playSoundFileNamed("Clap", waitForCompletion: false))
                print(z)
            case "Kick":
                self.run(SKAction.playSoundFileNamed("Kick", waitForCompletion: false))
                print(z)

            default: print("Shit hpns")
            }

        }

    }

}

override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered
}
}

printing names

【问题讨论】:

  • 您总是可以通过只做 5 次中的 4 次来运行实验,然后查看“Tom”、“11”、“12”是否正常播放。
  • 哦!好主意!我查了一下,它提供了一些新信息,但仍然不明白。现在可以正常播放:12、11、Tom and Chant。所以,4个声音而不是3个。不错)但是如果我做5个中的3个,只有Chant会发出声音......
  • 添加结果图片以获得更多视觉反馈
  • 我没有崩溃。我正在使用 wav。在这种情况下,我不完全了解“强参考”是什么(对不起,我是新手),但有些垫子可以正常工作。所以,我猜是算法中的问题。

标签: sprite-kit swift3


【解决方案1】:

AVAudioPlayer 与 SKAction 不同,因此不需要您调用的 do/catch 方法来使用您的声音名称准备 AVAudioPlayer。 AVAudioPlayer 主要用于背景音乐。

因此,您可以像在 touches started 方法中所做的那样简单地调用 SKAction,无需任何预先设置。您通常会这样称呼它们,名称中带有正确的文件扩展名。

run(SKAction.playSoundFileNamed("Kick.wav", waitForCompletion: false))

作为提示,您应该将这些声音动作创建为您的类的属性,以便它们被预加载并准备好使用。如果您只是直接在 touchesBegan 方法中调用该操作,您很可能会在第一次需要预加载声音文件时看到一些延迟/卡顿。

试试这样的

 enum SoundName: String { // store sound names like this to avoid typos
     case kick = "Kick.wav"
     case klap = "Klap.wav"
     ...
 }

 var sounds = [String: SKAction]()
 var soundNames = [SoundName.kick.rawValue, SoundName.klap.rawValue, etc]

比你这样设置它们

func didMove(to view: SKView) {

     for soundName in soundNames {
          let soundAction = SKAction.playSoundFileNamed(sound, waitForCompletion: false) 
          sounds.updateValue(soundAction, forKey: soundName)
     }
}

当你想玩它们时,你可以这样说

if let sound = sounds[SoundName.kick.rawValue] { // safely unwrap dict value as it might not exist
    run(sound)
}

还要确保在创建精灵/垫时正确设置节点名称,否则 touchesBegan 中的 switch 语句将不起作用。 不知道为什么你在那一点上有2个循环。检查该部分并确保您的焊盘具有正确的名称,使用打印语句查看发生了什么。

在你的 touchesMethod 中也试试这个。

   override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
       for touch in touches {
            let location = touch.location(in: self)
            let node = atPoint(location)

            if let nodeName = node.name {

                 switch nodeName {

                 case SoundName.kick.rawValue:
                       if let sound = sounds[SoundName.kick.rawValue] {
                          run(sound)
                        }  
                ...
                default:
                   break
            }
       }
  }

希望对你有帮助

【讨论】:

  • 感谢您的回答。我会尝试这样做。但是我在代码中的错误我没有得到)关于循环的地方 - 我这样做是因为它是一个 3x5 的垫子网格。像鼓机
  • 奇怪的是,最后只有 3 个焊盘能触碰。没有其他人。
  • 是的,我刚刚看到了。我也很困惑,因为您创建了一个 var i = 1 属性,然后在 for 循环中增加它。通常你可以直接在循环中添加它,比如 "for i in 1...5 { }" 。也许试试这个,看看会发生什么。
  • 垫子是按声音数组的顺序添加的吗?所以声音 1(踢)应该是 pad 1,声音 2(klap)应该是 pad 2 等等?
  • 我使用“var i”仅用于在数组中导航。我们可以想象我只想命名一个标签,这很好!它为标签提供正确的名称。它甚至为节点提供了正确的名称,因为我试图在新数组中添加所有焊盘名称以检查它们是否都收到了一个名称。也许问题根本不在名称上?该死的,这个麻烦在第二天晚上让我心烦意乱。我 99% 确定存在一些愚蠢的错误,例如错误的顺序或类似的东西,但我还看不到它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-24
  • 1970-01-01
相关资源
最近更新 更多