Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot create subclass of SKSpriteNode

Trying to subclass SKSpriteNode so make my game code cleaner, and I'm obviously not understanding something. Here's a very simple example: I create a new Swift file called Alien.swift with the following contents:

import SpriteKit

class Alien: SKSpriteNode {

}

In my game, I do:

    let alienSprite: Alien = Alien()
    print("It's an \(alienSprite)")

and I get:

It's an (SKSpriteNode) name:'(null)...'

Even Xcode says it's an 'aliensSprite':

enter image description here

Why, at run-time, is it not printing that it's an 'alienSprite'?

Edit: incorporating one of my comments here - I'm actually picking up the sprite from my .sks file, where I placed it with the scene editor and set its custom class. I try to pick it up with:

let alien = childNodeWithName("alien") as! alienSprite 

but I get the error:

Cannot cast SKSpriteNode to alientSprite
like image 707
Steve Ives Avatar asked Oct 18 '16 21:10

Steve Ives


3 Answers

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. enter image description here

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.

enter image description here

like image 132
Knight0fDragon Avatar answered Nov 01 '22 04:11

Knight0fDragon


You are not using the name of the variable

When you declare

 let alienSprite: Alien = Alien()

You are basically creating an empty SKSpriteNode. This means when you do the string interpolation, you are printing the actual SKSpriteNode and its properties.

To fix this, you have two options.

Original

  1. Print the type of alienSprite:

    print("It's an \(type(of: alienSprite))")
    
  2. Set the name of the Alien and print that:

    alienSprite.name = "Alien"
    print("It's an \(alienSprite.name)")
    

10/25/16

If you want something like @Knight0fDragon, you can do the following:

print("It's an \(type(of: alienSprite)) \(alienSprite)")

Which is basically an add on the my original answer.

like image 37
Jack Avatar answered Nov 01 '22 02:11

Jack


When you print an object, as in print("It's an \(alienSprite)"), you just ask to see its description property. By default for an SKNode this property just prints the name property of the object, as you didn't redefined this behavior you get the message (SKSpriteNode) name: null. If you want to redefine it then change the description in your new class to something more convenient, something like this should work:

class Alien : SKSpriteNode {
    override var description: String {
        return "\(String(describing: type(of:self)))"
    }
}

Remind that you also have a similar debugDescription to control what is printed by the debugger.

like image 44
Jean-Baptiste Yunès Avatar answered Nov 01 '22 04:11

Jean-Baptiste Yunès