I'm writing a game in SpriteKit that has a joystick to control the player. Previously, I had kept most of the joystick logic in the main GameScene's touchesBegan
, touchesMoved
, and touchesEnded
methods.
Since I have multiple SKScenes
, I wanted to abstract this logic out into a SKSpriteNode
subclass JoyStick
that contains its own touches
event handlers. This seems like a good solution as it automatically handles whether or not the touch is "in bounds" of the joystick and allows me to remove logic from the scene itself.
However, I can't find any good resources outlining how to properly pass information back and forth between a SKScene
and a SKSpriteNode
instance that has implemented touch event handlers. I could pass the JoyStick an instance of the object that I want to modify (like the player sprite) but I'm curious if there is a proper way to pass data back and forth without coupling the joystick to a specific "instance-to-modify".
Additionally, are there any other downsides to implementing touch event handlers in my SKSpriteNode instances, rather than handling everything in the scene's handlers?
I like to handle as much of the code in the object class as possible. So I would handle any of the object touch code inside of it's class file and send the touch back to the scene to be handle separately by the scene if needed, and use delegation to send the information regarding the touch to the scene.
There are no downsides to removing this code, and several upsides.
cleaner code faster loading time in xcode if the scenes have less line (my own findings) you don't have to pinpoint the node that the touch is landing on because it is encapsulated in a sublass
In subclass (cat)
protocol CatDelegate: class{
func catTouched(cat: Cat)
}
class Cat: SKSpriteNode {
weak var delegate: CatDelegate!
var isEnabled = true
var sendTouchesToScene = true
var color: SKColor = .white
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent!) {
guard isEnabled else { return }
//send touch to scene if you need to handle further touches by the scene
if sendTouchesToScene {
super.touchesBegan(touches, with event)
}
//handle touches for cat
delegate?.catTouched(cat: self)
}
}
meanwhile in Game Scene...
class GameScene: SKScene {
private var cat1: Cat!
private var cat2: Cat!
…
func createCats() {
cat1 = Cat()
cat1.color = .magenta
cat1.delegate = self
addChild(cat1)
cat2 = Cat()
cat2.color = .green
cat2.delegate = self
addChild(cat2)
}
}
extension GameScene: CatDelegate {
func catTouched(cat: Cat) {
print("cat of color \(cat.color)")
}
}