Skspritenode Subclassing Swift

Make SKSpriteNode subclass using Swift

You have to call the designated initializer for SKSpriteNode. I'm actually surprised you didn't get another error about not full implementing SKSpriteNode, are you using an older Xcode6 beta maybe?

Since you have to use the designated initializer, you need to call super.init(texture: '', color: '', size: '').

It would be something like this:

class Ball: SKSpriteNode {
init() {
let texture = SKTexture(imageNamed: "ball")
super.init(texture: texture, color: nil, size: texture.size())
}

required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

Note: I also added the init for NSCoder which Xcode will require.

How to create subclass of SKSpriteNode in Swift 3

Turns out my code is fine, the bugs were due to something else. If anyone sees this - it is now that easy to add new attributes to a subclass - you don't have to faff around with super inits etc.

print(Ci.pitch) 

will now give "middle C".

Why am I unable to subclass the SKSpriteNode

In Swift, you need to call an initializer that is implemented directly from your super class, in this case, SKSpriteNode. super.init() is implemented by another class that is in SKSpriteNode's inheritance tree, like SKNode or NSObject. You can always check the documentation for which constructors can you call for each class. It's very important to pay understand that you need to call designated initializers in your subclass

For example, you can do

class GuessSlot : SKSpriteNode{
init(color: SKColor, size: CGSize) {
super.init(texture: nil, color: color, size: size)
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}

SKSpriteNode subclassing swift

Just change your convenience initializer to this:

convenience init(imageNamed: String!, currentPiece: Type) {
let color = UIColor()
let texture = SKTexture(imageNamed: imageNamed)
let size = CGSizeMake(100.0, 100.0)
self.init(texture: texture, color: color, size: size)
self.piecetype = currentPiece
}

In Swift, a convenience initializer must:

  • Call another convenience initializer of the same class or the designated initializer of the class (not the superclass)
  • Use self only after calling self.init[...]

See the Swift Documentation on initializer for help: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-XID_323

Hope this helps,

Am unable to subclass SKSpriteNode using an image name

Just use the full initializer on the super, like so...

class MyBall : SKSpriteNode{

init(iNamed: String) {
let texture = SKTexture(imageNamed: iNamed)
super.init(texture: texture, color: .clear, size: texture.size())
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

Using properties of SKSpriteNode for subclass

Not sure if this is what you're asking, but, generally, if you create a subclass of an object, you don't need to do anything special to access the superclass's properties. They'll be initialized in the usual fashion.

However, you DO have to ensure that the superclass's initializers get called in a proper manner if you have your own initializers for your subclass.

In the case of a subclass of SKSpriteNode, if you define your own initializer for the subclass, that initializer will need to call the designated superclass initializer, which passes in the texture, color, and size to use for the sprite:

init(enemyType:String) {
let texture = SKTexture(imageNamed: "enemy_\(enemyType)")
let color = UIColor.black
let size = texture.size()
super.init(texture: texture, color: color, size: size)
}

Cannot create subclass of SKSpriteNode

Take notice to the state of your scene file. If you see it shaded, this means it has not saved yet. If you compile your code while still in the scene editor, the save will not happen, so be sure to hit cmd + s to save prior to compiling.
Sample Image

Now in case people are trying to figure out why class names are not saving, make sure you hit ENTER or leave the text field and go to another textfield to ensure that the class name saves, otherwise it will revert back to an older state.

Sample Image

Changing texture for subclass of SKSpriteNode?

Your code works well. In fact this SO answer is correct.

About SKSpriteNode subclass, the update method is a new custom function added by you, because the instance method update(_:) is valid only for SKScene class, this just to say that this function is not performed if it is not called explicitly.

To make a test about your class you can change your code as below( I've changed only textureForLevel method only to make this example):

class CharacterNode: SKSpriteNode {
let spriteSize = CGSize(width: 70, height: 100)
var level = 0
init(level: Int) {
self.level = level
super.init(texture: nil, color: UIColor.clear, size: spriteSize)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func update(level: Int) {
self.level = level
self.texture = textureForLevel(level: level)
}
func textureForLevel(level: Int) -> SKTexture {
if level == 3 {
return SKTexture(imageNamed: "TestTexture3.jpg")
}
return SKTexture(imageNamed: "TestTexture.jpg")
}
}

class GameScene: SKScene {
override func didMove(to view: SKView) {
let characterNode = CharacterNode(level:2)
characterNode.update(level:2)
addChild(characterNode)
characterNode.position = CGPoint(x:self.frame.midX,y:self.frame.midY)
characterNode.run(SKAction.wait(forDuration: 2.0), completion: {
characterNode.update(level:3)
})
}
}

As you can see when you launch GameScene a characterNode sprite will be shown in the center of the screen. After 2 seconds, the texture will change.



Related Topics



Leave a reply



Submit