所以我解决了我的另一个问题关于减少重复代码通过构建一个buildCharacter方法像这样-
func buildCharacter(name:String, height: CGFloat, width: CGFloat, position: CGPoint, zPosition: CGFloat) {
let animatedAtlas = SKTextureAtlas(named: name)
var animationFrames: [SKTexture] = []
let numImages = animatedAtlas.textureNames.count
for i in 1...numImages {
let textureName = "(name)(i)"
animationFrames.append(animatedAtlas.textureNamed(textureName))
}
animatedCharacter = animationFrames
let firstFrameTexture = animatedCharacter[0]
builtCharacter = SKSpriteNode(texture: firstFrameTexture)
builtCharacter.size.height = height
builtCharacter.size.width = width
builtCharacter.position = position
builtCharacter.zPosition = zPosition
builtCharacter.name = name
isUserInteractionEnabled = true
addChild(builtCharacter)
}
然后我在每个场景的基础上调用它们,像这样-
buildCharacter(name: "Bear", height: 370, width: 370, position: CGPoint(x: 295, y: 25), zPosition: 10)
buildCharacter(name: "Cat", height: 240, width: 240, position: CGPoint(x: 134, y: -38), zPosition: 12)
这在构建和添加它们到场景中非常有效,但是我正在努力检测触摸,然后将它们动画化。我之前的TouchesBegan看起来像这样-
func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
if let touch = touches.first {
let location = touch.location(in: self)
var closest:CGFloat?
let nodes = nodes(at:location)
for node in nodes as [SKNode] {
if let sprite = node as? SKSpriteNode {
// Calculate the distance from the node to the touch
let dx = location.x - node.position.x
let dy = location.y - node.position.y
let distance = dx*dx + dy*dy
// Find the closest
if closest == nil || distance < closest! {
closest = distance
selectedNode = sprite
}
}
}
}
switch selectedNode {
case bear:
if builtCharacter.hasActions() {
SoundEngine.shared.stopBackgroundMusic(fadeOut: false)
stopAllAnimation()
} else {
SoundEngine.shared.playBackgroundMusic("blueRail.aif", loop: false)
startAllAnimation()
}
case cat:
if cat.hasActions() {
SoundEngine.shared.stopBackgroundMusic(fadeOut: false)
stopAllAnimation()
} else {
SoundEngine.shared.playBackgroundMusic("cluckOldHen.aif", loop: false)
animateCat()
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
self.startAllAnimation()
}
}
所以基本上我正在努力访问节点名称?我尝试了builtCharacter.name,但无法找出它…我想我可以在TouchesBegan中做一些不同的事情,或者在buildCharacter方法中添加一些东西?
我知道我可以很容易地在故事板中做到这一点,这是我的备用计划-只是试图通过这种方法学习更多。提前感谢!
好吧,在@Mark Szymczyk的帮助下,我明白了。由于SKNode的name属性是可选的,所以我必须在if let语句中运行开关,并打开非可选的name
if let nodeName = selectedNode.name {
switch nodeName {
case "Bear" :
print("Bear touched")
case "Cat":
print("Cat touched")
default:
print("No node touched")
现在我可以访问节点名并检测触摸。