I am a Swift noob and could really use some advice. I am trying to create a class that builds a block in my SpriteKit scene by passing a few paramters for size and color through to the class. The code builds and the blocks DO appear in the scene BUT by printing out the node tree, I can see I am getting an empty node/container wrapping my blocks (maybe from the two addChilds?!). I am guessing I am doing more than one thing wrong here and would really love to understand how to structure this cleaner.
In my scene:
for i in 1...4! {
let block = Block(blockCount: i, blockSize: "Large", blocksColor: blocksColor)
blocksContainer?.addChild(block)
}
And my class:
import SpriteKit
class Block: SKShapeNode {
var block : SKSpriteNode?
private var blockCount: Int
private var blockSize: String
private var blocksColor: UIColor
init(blockCount: Int?, blockSize: String?, blocksColor: UIColor?) {
self.blockCount = blockCount!
self.blockSize = blockSize!
self.blocksColor = blocksColor!
super.init()
var blockSizePixels: Int
if (blockSize == "XLarge") {
blockSizePixels = 232
} else if (blockSize == "Large") {
blockSizePixels = 152
} else if (blockSize == "Medium") {
blockSizePixels = 104
} else if (blockSize == "Small") {
blockSizePixels = 56
} else {
blockSizePixels = 32
}
//build block
block = SKSpriteNode(color: blocksColor!, size: CGSize(width: blockSizePixels, height: blockSizePixels))
block!.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: blockSizePixels, height: blockSizePixels))
block!.position = CGPoint(x: Int.random(in: -100...100), y: 300)
block!.physicsBody!.friction = 0.05
block!.physicsBody!.restitution = 0.6
block!.physicsBody!.mass = 1.0
block!.name = "block" + String(self.blockCount)
self.addChild(block!)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
And my node tree print out comes out as:
Optional("blocksContainer")
nil <- empty node
Optional("block1")
nil
Optional("block2")
nil
Optional("block3")
nil
Optional("block4")
With help from @Paulw11 I refactored my class to be the following... taking out the multiple sprites and replacing them with a path. Nice!
import SpriteKit
class Block: SKShapeNode {
private var blockCount: Int
private var blockSize: String
private var blocksColor: UIColor
init(blockCount: Int?, blockSize: String?, blocksColor: UIColor?) {
self.blockCount = blockCount!
self.blockSize = blockSize!
self.blocksColor = blocksColor!
super.init()
//isUserInteractionEnabled = false
var blockSizePixels: Int
if (blockSize == "XLarge") {
blockSizePixels = XLarge
} else if (blockSize == "Large") {
blockSizePixels = Large
} else if (blockSize == "Medium") {
blockSizePixels = Medium
} else if (blockSize == "Small") {
blockSizePixels = Small
} else {
blockSizePixels = Tiny
}
//build block
self.path = CGPath(rect: CGRect(origin: CGPoint(x: -blockSizePixels/2, y: -blockSizePixels/2), size: CGSize(width: blockSizePixels, height: blockSizePixels)), transform: nil)
self.fillColor = blocksColor!
self.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: blockSizePixels, height: blockSizePixels))
self.position = CGPoint(x: Int.random(in: -100...100), y: 300)
self.physicsBody!.friction = 0.05
self.physicsBody!.restitution = 0.6
self.physicsBody!.mass = 1.0
self.name = "block" + String(self.blockCount)
}
class func classMethod() {
print ("hello from the class method")
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}