objective c - Create a subclass of a SKSpriteNode subclass -
let's want create bunch of different types of spaceships. want setup base spaceship class can use create other spaceships minor differences.
my base class looks this.
// basespaceship.h @interface spaceshipnode : skspritenode @property nscolor color; @property cgfloat enginethrust; + (id)basespaceshipwithimagenamed:(nsstring *)name; @end // basespaceship.m @implementation basespaceship + (id)basespaceshipwithimagenamed:(nsstring *)name { basespaceship *ship = [basespaceship spritenodewithimagenamed:name]; ship.color = [nscolor redcolor]; ship.enginethrust = 2.0; return ship; } @end
i can create ship in myscene.m fine.
basespaceship *baseclass = [basespaceship basespaceshipwithimagenamed:@"baseship"];
however, i'm not sure how create subclass of basespaceship
, example, destroyerspaceship
. i'm not sure if should using static methods or not. examples i've seen online use static methods instantiate skspritenode
s. came with, it's wrong.
// destroyerspaceship.h @interface destroyerspaceship : basespaceship @property cgfloat missilethrust; - (id)makedestroyerspaceship; @end // destroyerspaceship.m @implementation destroyerspaceship - (id)makedestroyerspaceship{ destroyerspaceship *ship = [destroyerspaceship basespaceshipwithimagenamed:@"destroyership"]; ship.enginethrust = 2.0; // ship doesn't have missilethrust, program crashes ship.missilethrust = 3.0; return ship; } @end
ultimately, want able this.
destroyerspaceship* = [destroyerspaceship makedestroyerspaceship]; evilspaceship* b = [evilspaceship makeevilspaceship]; nicespaceship* c = [nicespaceship makenicespaceship];
and have them inherit basic properties , methods basespaceship
.
the answer less complex think. well, code might bit more complex, once have structure flexible. creating different types of spaceships lot more readable.
you can override initializer method in subclass. sidenote, use (instancetype)
instead of (id)
(source: instancetype @ nshipster).
as adding custom body sprites object, opt subclass sknode instead of skspritenode (so @interface spaceshipnode : sknode
instead of @interface spaceshipnode : skspritenode
).
@interface spaceshipnode : sknode @property skcolor * color; // use skcolor instead of nscolor @property cgfloat enginethrust; @end // ... @implementation spaceshipnode - (instancetype) init { if (self == [super init]) { nslog(@"a new spaceshipnode init'ed."); // set default initial values here brand-new spaceshipnodes inherit // perhaps create , add basic body sprite // skspritenode * body = ...; // [self addchild:body]; // set thrust self.enginethrust = 2.0; } return self; }
then can subclass , create new type of spaceship. awesome!
@interface destroyerspaceship : spaceshipnode @property cgfloat missilethrust; @end @implementation destroyerspaceship - (instancetype) init { // note [super init] call spaceshipnode's init method if (self = [super init]) { nslog(@"a new destroyerspaceship init'ed."); // add body sprite // skspritenode * body = ...; // [self addchild:body]; // destroyer faster average spaceship self.enginethrust = 10.0; // set class specific variables self.missilethrust = 5.f; } return self; }
now, can call:
spaceshipnode * newspaceship = [spaceshipnode new]; // short [[spaceshipnode alloc] init]; destroyerspaceship * newdestroyer = [destroyerspaceship new];
these 2 lines log following. last 2 lines caused destroyer, first calls spaceshipnode
init
, , destroyer-specific init
method.
a new spaceshipnode init'ed.
a new spaceshipnode init'ed.
a new destroyerspaceship init'ed.
and can use this:
spaceshipnode * newunidentifiedvessel = [destroyerspaceship new]; if ([newunidentifiedvessel iskindofclass:[destroyerspaceship class]]) { nslog(@"we under attack! route power shields!"); }
Comments
Post a Comment