Unable to initialized a class that subclasses SKShapeNode, specifically (rectOf: CGSize)

Am trying to subclass SKShapeNode yet it never works. Specifically the SKShapeNode(rectOf: CGSize).

Trying to use init(), super.init, and sometimes the compiler tells me to use the designated initializer, which I cannot find to save my life. Am using Xcode 11 and Swift 5.

Here is a sample of one of my declaration attempts and my call. The self element in the call is from the background pic. It works if I create an SKShapeNode directly using the same parameters. But would like to subclass this so I can add custom methods and properties.

I've scoured the internet and so many other forums. Not one reply. I'm desperate at this point.

Thank you

p.s. I apologize this is a repost. But I only realized too late that I used the wrong tags.

In this sample code I removed all the part that fill color, and position, set the zPosition, etc. because it all works if I do it straight from my GameScene, without using a custom SubClassed attempt.

Code Block
class PegBase : SKShapeNode {
init(rectOfPegBase: CGSize) {
    super.init()    
self.fillColor = SKColor.red    
self.strokeColor = SKColor.red
self.Position = 0
}  
required init?(coder aDecoder: NSCoder) {       fatalError("init(coder:) has not been implemented")   
}}
let childP = PegBase(rectOfPegBase: CGSize(width: self.size.width * 0.8, height: self.size.height * 0.2))
self.addChild(childP) 

Answered by SergioDCQ in 620429022
Ok, the code below works, as I can tell because the pegBaseBoard is filled with red. So if I consider this step one, how do I start passing extra parameters so I can set the fill, and other properties in the subClass file?


i
Code Block
mport Foundation
import SpriteKit
class PegBaseBoard : SKShapeNode
{
    override init() {
        super.init()
    }
    required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
    }
}


Code Block
import SpriteKit
import GameplayKit
class GameScene: SKScene, SKPhysicsContactDelegate
{
var pegBaseBoard = PegBaseBoard()
    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)
pegBaseBoard = PegBaseBoard.init(rectOf : CGSize(width: self.size.width * 0.8, height: self.size.height * 0.2))
pegBaseBoard.fillColor = SKColor.red
self.addChild(pegBaseBoard)
  }
}


Where do you run this code ? In a playground ?
Where do you call lines 12 and 14 ?

When testing, I found several problems:

line 6: Position is not defined. Where did you declare it ?
line 12: self element in the call is from the background pic: please show real complete code, that will be easier.

So, show the real code
Tell what you expect
Tell what you get and precise error messages.


First of all, you should better read this section of the Swift Book.

Class Inheritance and Initialization


Some points in your case:
  • In SKShapeNode, init(rectOf:) is a convenience initializer

  • To call a convenience initializer in your own initializer, the convenience initializer needs to be inherited and your own initializer needs to be another convenience initializer

  • To inherit convenience initializers, you need to [1] inherit all the designated initializers or [2] define (override) all the designated initializers

  • ... (You should better read all other parts of the section carefully.)

Thus, conclusion.
Code Block
class PegBase : SKShapeNode {
//To use `init(rectOf:)`, your own init needs to be a convenience initializer
convenience init(rectOfPegBase size: CGSize) {
//Call `self.init(rectOf:)`, which needs to be inherited from super class
self.init(rectOf: size)
self.fillColor = SKColor.red
self.strokeColor = SKColor.red
self.position = .zero
}
//
//To inherit `init(rectOf:)`, you need to override all the designated initializers...
//
override init() {
super.init()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}


Or you can write something like this:
Code Block
class PegBase : SKShapeNode {
//To use `init(rectOf:)`, your own init needs to be a convenience initializer
convenience init(rectOfPegBase size: CGSize) {
//Call `self.init(rectOf:)`, which needs to be inherited from super class
self.init(rectOf: size)
self.fillColor = SKColor.red
self.strokeColor = SKColor.red
self.position = .zero
}
//
//Or you need to inherit all the designated initializers, by NOT defining any designated initializers
//
}


Well below is as close as I could get to your code. It compiles, but at runtime I get an

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
error, which I assume is because the object never gets created.

Thanks for your reply and I promise to start reading that section, but with me being new at Swift, it might take me a while. So any obvious errors you could point out would be greatly apperciated.

Thanks again

Code Block
/*  GameScene.swift
*/
import SpriteKit
import GameplayKit
class GameScene: SKScene, SKPhysicsContactDelegate
{
    var pegBaseBoard : PegBaseBoard?
    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)
    pegBaseBoard! = PegBaseBoard.init(rectOfPegBase : CGSize(width: self.size.width * 0.8, height: self.size.height * 0.2))
    self.addChild(pegBaseBoard!)
    }
}

Code Block
/*
//  PegBaseBoard.swift
*/
import Foundation
import SpriteKit
class PegBaseBoard : SKShapeNode
{
        convenience init(rectOfPegBase size: CGSize) {
        self.init(rectOf: size)
        self.fillColor = SKColor.red
        self.strokeColor = SKColor.red
        self.position = .zero
}
    override init() {
        super.init()
    }
    required init?(coder aDecoder: NSCoder) {
   fatalError("init(coder:) has not been implemented")
    }
}

Seems you need to learn one more important thing before reading the article.

You should start a new thread, if your new question is different than the original question.
That is the right manner to use Q&A sites like this.

Please include a link to this thread, when you start a thread for your Unexpectedly found nil issue.
Forgive my inexperience in Swift, but isn't this a problem with my subclass not initializing. Sure I could start thread for that, but then I would have I wait for it to return anyway, no?

Right now, if I could just make my subclass do the same as SKShapeNode(rectOf: CGSize), I would be happy.
@SergioDCQ

but isn't this a problem with my subclass not initializing. 

Sorry, I was not clear enough in my previous reply. But the answer is NO.

You are using forced unwrapping in a wrong manner and that has nothing to do with initialization of PegBaseBoard.
Accepted Answer
Ok, the code below works, as I can tell because the pegBaseBoard is filled with red. So if I consider this step one, how do I start passing extra parameters so I can set the fill, and other properties in the subClass file?


i
Code Block
mport Foundation
import SpriteKit
class PegBaseBoard : SKShapeNode
{
    override init() {
        super.init()
    }
    required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
    }
}


Code Block
import SpriteKit
import GameplayKit
class GameScene: SKScene, SKPhysicsContactDelegate
{
var pegBaseBoard = PegBaseBoard()
    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)
pegBaseBoard = PegBaseBoard.init(rectOf : CGSize(width: self.size.width * 0.8, height: self.size.height * 0.2))
pegBaseBoard.fillColor = SKColor.red
self.addChild(pegBaseBoard)
  }
}


Please follow the rule, one thread, one topic.

The issue Unable to initialized a class that subclasses SKShapeNode, specifically (rectOf: CGSize) is SOLVED, no?
You should start a new thread for a new question.

Unable to initialized a class that subclasses SKShapeNode, specifically (rectOf: CGSize)
 
 
Q