3

I'm working on a Breakout type game. I created the paddle in a different scene (PaddleScene.sks) so I could reference it across multiple levels. Not sure if that's how it's done yet, still a newbie.

I added the paddle inside GameScene.sks through SKReferenceNode and referenced it in code like this:

paddle = self.childNode(withName: "//paddle") as! SKSpriteNode

This works, but the problem is that now paddle.position.x gives me 0, because that is its position inside PaddleScene.sks. So I have to use the SKReferenceNode to get the position inside GameScene.

paddleRef = self.childNode(withName: "paddleScene") as! SKReferenceNode

So now I have to keep track of two variables instead of one. Is there an easier way to import external objects in my scenes without having multiple variables?

Norbert
  • 2,741
  • 8
  • 56
  • 111

2 Answers2

1

Can you post the code that you use to create the paddle? Also the code that you use to reference the paddle in your GameScene?

The referenced node (in your case the paddle) is a childnode of the SKReferenceNode. This means that your paddle assignment line should read:

let paddle = paddleRef.childNode(withName: "paddle")

Then you should only need to work with paddle rather than with paddleRef.

Alternatively I would create a dedicated class for the paddle, as a subclass of SKSpriteNode. It would deal with everything related to the paddle - it's position, rotation, size, transparency, image, color tint, etc.

Then it becomes really easy to reuse the paddle in any of your scenes - just create an instance of this class within the scene code, like that:

let paddle = Paddle()

(I assume you would name your paddle class "Paddle"). Then you are dealing with only one object and your paddle properties will work just fine - paddle.position, paddle.zRotation, paddle.size, etc.

If you need any help of how to setup the paddle class, let me know.

Stoyan

Stoyan
  • 320
  • 1
  • 9
  • This doesn't answer his question. He could & should setup his paddle as a subclass if it has any more data other being a SKSpriteNode but that doesn't answer his question about import SKReferenceNodes from his sks file – Ron Myschuk Mar 18 '17 at 18:20
  • 1
    Point taken. I overlooked the possibility of him using the Scene Editor. I hope that I now provide a proper answer. Thanks for pointing that out! – Stoyan Mar 18 '17 at 19:32
  • I created a different scene with a custom dimension that hosts just the paddle. I didn't use any code for that, thinking it would make things more easier to visualise. I then used the Reference object in the main scene to reference the paddle, just to make the most of the visual editor and make things easier to modify. Is that wrong in any way? Or does it cause performance issues? Would you recommend creating it as a subclass of SKSpriteNode instead? – Norbert Mar 18 '17 at 20:45
  • To tell you the truth, I have never used the scene editor extensively. I would only use it if I have to create some sprite-rich levels that would be painful to arrange in a programmatic way. But I feel it's much cleaner to keep game sprites just as SKSpriteNodes or as SKSpriteNode subclasses defined in a separate file - this provides the ability to attach additional properties to them such as score, timers, etc. Obviously in your case this is not a requirement, so clearly it's your call. Did you try using the paddle child of the reference node? Is it now properly reacting to property changes? – Stoyan Mar 18 '17 at 20:54
  • 1
    I put my ball and paddle in separate files as `SKSpriteNode` subclasses. I thought it would be messier, but it feels right. I'll add the paddle and ball in the `GameScene` class and use that as a base scene of sorts and have all the levels inherit it. If I have any level specific changes for the ball, I can just overwrite it in that level's scene. Things are making more sense now. Thanks so much! – Norbert Mar 18 '17 at 23:39
1

I recently started using the scene editor for everything (almost), and I love having the visual layout for my objects. I create scene (sks) file for complex objects (not just scenes) and I place them in my scene files using reference nodes, so that I can reuse them in multiple scene and visual see how they layout. I've not really found a way around the double reference, but this is how I handle the reference nodes in code. This method allows me to lay them out in the scene editor but still get there positioning without caring around the extra objects.

if let paddleReference = self.childNode(withName: "paddle") as? SKReferenceNode {

    let paddleNode = paddleReference.getBasedChildNode() as? SKSpriteNode

    self.paddle = paddleNode?.copy() as! SKSpriteNode
    paddle.position = (paddleReference.position)
    addChild(paddle)
    paddleNode?.removeFromParent()
    print("paddle.position \(paddle.position)")
}


extension SKReferenceNode {

    func getBasedChildNode() -> SKNode? {
        if let child = self.children.first?.children.first { return child }
        else { return nil }
    }
}

credit goes to @SimonePistecchia for this extension Add SKReferenceNode/SKScene to another SKScene in SpriteKit

Community
  • 1
  • 1
Ron Myschuk
  • 6,011
  • 2
  • 20
  • 32
  • That's a cool trick and will definitely use it in the future, but I decided to code the paddle in a separate `SKSpriteNode` class. – Norbert Mar 18 '17 at 23:32
  • That's good, this code is still relevant. I subclass most of my items, just change the class in the sks of your next root object below the scene node to your subclass. And then in code when looking for it on the getBasedChildNode just cast it as your subclass. I only put SKSpriteNode in the example because your question didn't state whether or not you had subclassed it – Ron Myschuk Mar 19 '17 at 00:30