Reputation: 47
Heyo folks, having a weird issue when trying to create a subclassed node in SpriteKit. I get no errors at compile, and app runs until I progress to where the node needs to be added as a child of the scene, then fails and says reason: 'Attemped to add nil node to parent:
I'm not sure what I'm missing, any help is appreciated! Here's my header for the node:
#import <SpriteKit/SpriteKit.h>
@interface Ships : SKSpriteNode
-(Ships *)initWithImageNamed: (NSString *)imageName;
@end
And here's the implementation:
#import "Ships.h"
@implementation Ships
-(Ships *)initWithImageNamed: (NSString *)imageName
{
self = [Ships spriteNodeWithImageNamed:imageName];
// Adds more accurate physics body for ship collisions
CGFloat offsetX = (self.frame.size.width * 1.2) * self.anchorPoint.x;
CGFloat offsetY = (self.frame.size.height * 1.2) * self.anchorPoint.y;
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 8 - offsetX, 30 - offsetY);
CGPathAddLineToPoint(path, NULL, 7 - offsetX, 22 - offsetY);
CGPathAddLineToPoint(path, NULL, 50 - offsetX, 2 - offsetY);
CGPathAddLineToPoint(path, NULL, 65 - offsetX, 7 - offsetY);
CGPathAddLineToPoint(path, NULL, 70 - offsetX, 8 - offsetY);
CGPathAddLineToPoint(path, NULL, 27 - offsetX, 31 - offsetY);
CGPathCloseSubpath(path);
self.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:path];
self.physicsBody.dynamic = NO;
self.physicsBody.restitution = 0.0f;
self.physicsBody.friction = 0.0f;
self.physicsBody.linearDamping = 1.0f;
self.physicsBody.allowsRotation = NO;
self.physicsBody.usesPreciseCollisionDetection = YES;
// Keeps player ship on top of all other objects(unless other objects are assigned greater z position
self.zPosition = 100.0f;
return self;
}
@end
Then in my scene, I declare playerNode
in interface
with: Ships *playerNode;
and here's the method that attempts to implement the node:
-(void) createPlayerNode
{
playerNode = [playerNode initWithImageNamed:@"Nova-L1"];
playerNode.position = CGPointMake(self.frame.size.width/5, self.frame.size.height/2);
playerNode.physicsBody.categoryBitMask = CollisionCategoryPlayer;
playerNode.physicsBody.collisionBitMask = 0;
playerNode.physicsBody.contactTestBitMask = CollisionCategoryBottom | CollisionCategoryObject | CollisionCategoryScore | CollisionCategoryPup;
[self addChild:playerNode];
}
and I call [self createPlayerNode];
elsewhere in the app, and as soon as I do...crash. Any help is greatly appreciated! Also, I'm running on my iPhone 5
Upvotes: 0
Views: 86
Reputation: 12773
The initializer for Ships is an instance method not a class method, so your alloc/init statement should be
playerNode = [[Ships alloc] initWithImageNamed:@"Nova-L1"]];
and in Ships.m, replace
self = [Ships spriteNodeWithImageNamed:imageName];
with this
self = [super initWithImageNamed:imageName];
Additionally, you should release the path after creating the physics body...
ship.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:path];
CGPathRelease(path);
Alternatively, you can declare a convenience method in Ships.m to alloc/init in a single step.
EDIT:
Declare class method in Ships.m
+ (Ships *)shipNodeWithImageNamed:(NSString *)imageName
{
return [[Ships alloc] initWithImageNamed:imageName];
}
Add method prototype to Ships.h
+ (Ships *)shipNodeWithImageNamed:(NSString *)imageName;
and create a new ship node by
playerNode = [Ships shipNodeWithImageNamed:@"Nova-L1"];
Upvotes: 2