Reputation: 684
So basically I have a node called tree and I designed it in a .sks file.
I added a custom class for the skspritenode but the custom class doesn't seem to affect the node.
I am trying to detect touches on the node and its children.
This node is being transfered to multiple scenes using removefromparent()
and addchild()
functions so instead of writing duplicate code on each scene to detect the touch I am trying to use the custom node class to do it... any help would be appreciated.
note i have super.init function with the texture as it is necessary but I would like to use the node that was already created in the scene.
My class code
import SpriteKit
class tree: SKSpriteNode {
init() {
let texture = SKTexture(imageNamed: "tree")
super.init(texture: texture, color: SKColor.clear, size: texture.size())
self.isUserInteractionEnabled = true
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
print("touched!")
}
}
}
Upvotes: 1
Views: 497
Reputation: 35392
There is a good explanation in this answer that should be clear your ideas about SKS files and subclassing.
About your code it is a good habit to use uppercase letter for the class names, in your case I prefer to use class Tree
instead of class tree.
About your second issue, you can use userData to transfer your object from a scene to another as explained below in my example:
import SpriteKit
class GameScene: SKScene {
private var label : SKLabelNode?
var tree : Tree!
override func didMove(to view: SKView) {
self.label = self.childNode(withName: "//helloLabel") as? SKLabelNode
if let label = self.label {
label.alpha = 0.0
label.run(SKAction.fadeIn(withDuration: 2.0))
}
self.isUserInteractionEnabled = true
tree = Tree()
tree.name = "tree"
addChild(tree)
tree.position = CGPoint(x:self.frame.midX,y:self.frame.midY)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch: AnyObject in touches {
let pointOfTouch = touch.location(in: self)
let nodeUserTapped = atPoint(pointOfTouch)
if nodeUserTapped.name == "tree" {
tree.removeFromParent()
let sceneToMoveTo = Scene2.init(size: self.size)
sceneToMoveTo.userData = NSMutableDictionary()
sceneToMoveTo.userData?.setObject(tree, forKey: "tree" as NSCopying)
let gameTransition = SKTransition.fade(withDuration: 0.5)
self.view!.presentScene(sceneToMoveTo, transition: gameTransition)
}
}
}
}
class Scene2: SKScene {
var tree:Tree!
override func didMove(to view: SKView) {
print("This is the scene: \(type(of:self))")
guard let previousValue = self.userData?.value(forKey: "tree") else { return }
if previousValue is Tree {
tree = previousValue as! Tree
addChild(tree)
tree.position = CGPoint(x:self.frame.midX,y:self.frame.midY)
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch: AnyObject in touches {
let pointOfTouch = touch.location(in: self)
let nodeUserTapped = atPoint(pointOfTouch)
if nodeUserTapped.name == "tree" {
tree.removeFromParent()
if let sceneToMoveTo = SKScene(fileNamed: "GameScene") {
sceneToMoveTo.scaleMode = .aspectFill
sceneToMoveTo.userData = NSMutableDictionary()
sceneToMoveTo.userData?.setObject(tree, forKey: "tree" as NSCopying)
let gameTransition = SKTransition.fade(withDuration: 0.5)
self.view!.presentScene(sceneToMoveTo, transition: gameTransition)
}
}
}
}
}
As you can read I've the control of touches both in my parent class and in my node, this can be made possible by changing the touchesBegan
method of your custom SKSpriteNode
as:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
print("touched!")
}
guard let parent = self.parent else { return }
parent.touchesBegan(touches, with: event)
}
Remember that you should extend this approach also to the other touches method if you want to use them..
Upvotes: 2