Reputation: 1004
I am trying to subclass SKSpriteNode so that I can use it to create different characters with different properties for a game. I know this should be a trivial task, but I am having a hard time understanding how to initialize a variable when instances are created. In the header I have:
#import <SpriteKit/SpriteKit.h>
@interface MyClass : SKSpriteNode
@property int myVariable;
@end
And in the implementation:
#import "MyClass.h"
@interface MyClass ()
@end
@implementation MyClass
@synthesize myVariable;
- (id)init {
if (self = [super init]) {
myVariable = 100;
}
return self;
}
When I create the node in the scene:
@implementation GameScene
{
MyClass *mySprite;
}
- (void)didMoveToView: (SKView *) view
{
mySprite = [MyClass spriteNodeWithImageNamed:@"image.png"];
}
The value of myVariable is 0, which I assume it means that spriteNodeWithImageNamed does not execute the init method. If I use:
mySprite = [[MyClass alloc] init]; // or mySprite = [MyClass new];
mySprite = [MyClass spriteNodeWithImageNamed:@"image.png"];
The variable name is correctly set to 100, but then reverted to 0 by spriteNodeWithImageNamed.
I have also tried:
mySprite = [[MyClass alloc] init]; // or mySprite = [MyClass new];
[mySprite setTexture:[SKTexture textureWithImageNamed:@"image.png"]];
In this case the value of myVariable is correct, but no image appears when I add the node to the scene. What init method is called when spriteNodeWithImageNamed is used? Am I improperly overriding the SKSpriteNode init method?
Upvotes: 1
Views: 780
Reputation: 7588
Here is how I do it. Create your own custom init method, and simply call the default spritenode initWithImage.
-(id)initShipWithType:(ShipType)type {
self = [super initWithImageNamed:[self getShipSprite:type]];
if (self) {
}
return self;
}
Upvotes: 0
Reputation: 1545
You have done everything correctly with creating a class, but you need to keep in mind that you are calling the factory method spriteNodeWithImageNamed
, which then initializes and allocates by itself. Thus, if you want to use your custom init
method you need to override the factory method as well.
Inside of your implementation of MyClass, override the method to call your initializer:
+ (instancetype) spriteNodeWithImageNamed:(NSString *)imageName{
MyClass *newClass = [[MyClass alloc] init];
SKTexture *spriteTexture = [SKTexture textureWithImageNamed:imageName];
newClass.size = spriteTexture.size;
newClass.texture = spriteTexture;
return newClass;
}
Hope this helps, let me know if you have questions.
*EDIT: Im actually a little tempted to ditch this, only because SKSpriteNode doesn't have an init
method (or at least not that we know of). So unless you want to dive deep into Apple's mysteries then just do it this way:
+ (instancetype) spriteNodeWithImageNamed:(NSString *)imageName{
MyClass *newClass = [[MyClass alloc] initWithImageNamed:imageName];
newClass.myVariable = 100;
return newClass;
}
You could instead override initWithImage
to put in myVariable, but the whole point is that I'd avoid trying to use the init
initializer with SKSpriteNode.
Upvotes: 3