Having more than one init in a subclass of SKShapeNode

Actually I have asked this question before, but since I didn't know what I was talking about, I couldn't ask it properly. people tried to help me, but I was too lost to better explain. Now, at least I know what I'm looking for.

At the very bottom I have subclassed SKShapeNode, and I call it with the proper parameters:

Code Block
pegPlaceHolder = placeHolderRect(rectOf: CGSize(width: 100, 100 ))


And all is well. What I'd like to know is there a way that I can call the subclass with added parameters so that the subclass calls the default init with the value of RectOf, as it is doing now. And then uses the other parameters within the init?

Code Block
class placeHolderRect : SKShapeNode
{
    var height: CGFloat = 0.0
    var width:  CGFloat = 0.0
    override init() {
        super.init()
        self.isHidden = true
        self.strokeColor = SKColor.green
        self.fillColor = SKColor.green
        self.zPosition = 0
    }
}


I can call the subclass with added parameters so that the subclass calls the default init with the value of RectOf, as it is doing now. And then uses the other parameters within the init?

Sorry, but I cannot understand what you are trying. Can you explain what you want to do with more concrete examples?

And your code of placeHolderRect (you should start type names with Capital letter in Swift) does not seem to be the actual code.
It does not accept placeHolderRect(rectOf: CGSize(width: 100, 100 )). Please show your actual code.
At the bottom is:
my GameViewController
my GameScene
and my subclassing of the SKShapeNode (there's some duplication I need to clean ups, but the code works

I initiate a new instance of the subclass
Code Block
pegPlaceHolder = PlaceHolderRect(rectOf: CGSize(width: self.size.width * 0.7, height: self.size.height * 0.2 ))

The init my subclass calls is this one from the documentation:

_init(rectOf: CGSize)

Then I do other things such as colors, positioning, etc.

What I would like to do, is my initialization of the subclass instance with more parameters. And with that one call send more parameters and have my subclass do the initial standard init, followed by another init with the addition parameters. This is what I cannot figure out how to do.

p.s. If you know of a way to copy Xcode into this forum, in proper formatting it would make it so much easier. I spend twice the time on here deleting the extra newlines, after the pasting the code here, then asking questions

The code is in the next reply as this post exceeds the limit
GameViewController
Code Block
import UIKit
import SpriteKit
import GameplayKit
class GameViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        if let view = self.view as! SKView?
        {
            // Build SKScene from background image
            let scene = GameScene(size: CGSize(width: 1536, height: 2048))
            // Set the scale mode to scale to fit the window
            scene.scaleMode = .aspectFit
            // Present the scene
            view.presentScene(scene)
            //change when done
            view.ignoresSiblingOrder = true
            view.showsFPS = true
            view.showsNodeCount = true
        }
    }
    override var shouldAutorotate: Bool {
        return true
    }
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if UIDevice.current.userInterfaceIdiom == .phone {
            return .allButUpsideDown
        } else {
            return .all
        }
    }
    override var prefersStatusBarHidden: Bool {
        return true
    }
}


GameScene
Code Block
import SpriteKit
import GameplayKit
class GameScene: SKScene, SKPhysicsContactDelegate
{
    var pegBase = pegBaseBoard()
    var pegPlaceHolder = PlaceHolderRect()
    class UISwipeGestureRecognizer : UIGestureRecognizer{
    }
  override func didMove(to view: SKView)
    {
        let backGround = SKSpriteNode(imageNamed: "background")
        backGround.size = self.size
        backGround.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
        backGround.zPosition = -1
        self.addChild(backGround)
        pegPlaceHolder = PlaceHolderRect(rectOf: CGSize(width: self.size.width * 0.7, height: self.size.height * 0.2 ))
        pegPlaceHolder.setDims(w: self.size.width * 0.7, h: self.size.height * 0.2)
        pegPlaceHolder.strokeColor = .green
        pegPlaceHolder.fillColor = .green
        pegPlaceHolder.zPosition = 0
        pegPlaceHolder.setFlush(dirFlush: .lefthanded, parent: backGround)
        self.addChild(pegPlaceHolder)
    }
}

PegBaseHolder subclass of SKShapeNode
Code Block
import Foundation
import SpriteKit
import GameplayKit
class PlaceHolderRect : SKShapeNode
{
    var height: CGFloat = 0.0
    var width:  CGFloat = 0.0
    override init() {
        super.init()
        self.isHidden = true
        self.strokeColor = SKColor.green
        self.fillColor = SKColor.green
        self.zPosition = 0
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    func setDims(w: CGFloat, h: CGFloat){
        width = w
        height = h
    }
    func setFlush (dirFlush: directionToFlush, parent: SKSpriteNode){
        var finalX: CGFloat
        let rectOf: CGRect = parent.calculateAccumulatedFrame()
        ///calculate modifier of x
        ///let modifier = difference between width of parent and width of child and divide it in half
        let xBase = (rectOf.size.width - self.width)/2
        switch dirFlush
        {
            case .lefthanded:
            finalX = (rectOf.size.width / 2) - xBase
            case .righthanded:
            finalX = (rectOf.size.width / 2) + xBase
        case .center:
            finalX = (rectOf.size.width / 2)
    }
        self.position = CGPoint(x: finalX, y: self.height/2)
        self.isHidden = false
    }
}

Thanks for showing your code. Now I can see that there exists init?(coder:), which is needed to make PlaceHolderRect(rectOf: CGSize(width: 100, 100 )) valid.

So, it is confirmed that your subclass of SKShapeNode has defined all the designated initializers of SKShapeNode.
That lets the subclass inherit all the convenience initializers of its parent class, including init(rectOf:).


Now you can add another initializer taking some more parameters in any of the following manners.
  • Add another designated initializer and call a designated initializer of the super class

(This needs to be inside the class definition.)
Code Block
//Add another designated initializer
init(rectOf size: CGSize, color: SKColor/*...*/) {
//You need to initialize all the own properties of your subclass
//...
        //Call a designated initializer of your super class
super.init()
//Do any other setups you need
//...
}

(In this case, you may need to set the path property by yourself.)
  • Add another convenience initializer and call any one of the initializers of your class

(This convenience initializers can be defined in an extension.)
Code Block
extension PlaceHolderRect {
//Add another convenience initializer
convenience init(rectOf size: CGSize,
isHidden: Bool,
strokeColor: SKColor,
fillColor: SKColor,
zPosition: CGFloat) {
//You need to initialize all the own properties of your subclass
//...
//Call any one of the initializers of your class
self.init(rectOf: size)
//Do any other setups you need
self.isHidden = isHidden
self.strokeColor = strokeColor
self.fillColor = fillColor
self.zPosition = zPosition
//...
}
}


I may be mistaking what you want to do. If this is not what you want, please explain it to me using other words or some more examples.



p.s. If you know of a way to copy Xcode into this forum, in proper formatting it would make it so much easier. I spend twice the time on here deleting the extra newlines, after the pasting the code here, then asking questions

If you are using Safari, please try Edit > Paste and Match Style. At least, it will make you free from deleting the extra newlines.
You got correct "what" it is that I want to.

Unable to implement it, too many errors. I think it's best that I move on and come back to this later.

Anyway to put an open question on hold? Or archive it?

Thanks for your help

Anyway to put an open question on hold? Or archive it?

Generally, you may keep it open until the original issue is really solved.
But updates to an existing thread would not get more attention than a new thread.

Anyway, when I find you come back (with enough info to solve, please!), I will do what I can do.
Having more than one init in a subclass of SKShapeNode
 
 
Q