请帮我找错。
我需要每个打击垫从阵列播放自己的声音,但只有打击垫13,14,15。同时我在每个打击垫上放置了一个带有节点名称的标签,这说明该节点有一个名称,所以看起来问题不在名称中,我不知道它是什么。 如果您对改进此代码有其他说法,请随意说,我是新手,很乐意听到。
我做错了什么?
由于
PS:我想说,我只是为了挑战而在精灵套件上做这件事。
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
}
}
答案 0 :(得分:1)
AVAudioPlayer与SKAction不同,因此不需要使用声音名称来准备AVAudioPlayer的do / catch方法。 AVAudioPlayer主要用于背景音乐。
所以你可以简单地调用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
}
}
}
希望这有帮助