假设我想创建一堆不同类型的太空飞船。我想设置一个基础太空船类,我可以用它来创建其他太小差异的太空飞船。
我的基类看起来像这样。
// 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
我可以在MyScene.m中创建一艘船就像这样。
BaseSpaceship *baseClass = [BaseSpaceship baseSpaceshipWithImageNamed:@"BaseShip"];
但是,我不确定如何创建BaseSpaceship
的子类,例如DestroyerSpaceship
。我不确定我是否应该使用静态方法。我在网上看到的例子使用静态方法来实例化SKSpriteNode
。这就是我提出的,但这是错误的。
// 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
最终,我希望能够做到这样的事情。
DestroyerSpaceship* a = [DestroyerSpaceship makeDestroyerSpaceship];
EvilSpaceship* b = [EvilSpaceship makeEvilSpaceship];
NiceSpaceship* c = [NiceSpaceship makeNiceSpaceship];
让他们都从BaseSpaceship
继承基本属性和方法。
答案 0 :(得分:7)
答案并不像你想象的那么复杂。好吧,代码可能有点复杂,但是一旦你有了结构,它就会变得最灵活。创建不同类型的宇宙飞船也会更具可读性。
您可以覆盖子类中的初始化方法。作为旁注,请使用(instancetype)
代替(id)
(来源:instancetype @ NSHipster)。
在向对象添加自定义正文精灵时,我会选择子类化SKNode而不是SKSpriteNode(所以@interface SpaceshipNode : SKNode
代替@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 was just init'ed.");
// set some default initial values here that all brand-new SpaceshipNodes will inherit
// perhaps create and add a basic body sprite
// SKSpriteNode * body = ...;
// [self addChild:body];
// set thrust
self.engineThrust = 2.0;
}
return self;
}
然后你可以继承并创建一种新型宇宙飞船。真棒!
@interface DestroyerSpaceship : SpaceshipNode
@property CGFloat missileThrust;
@end
@implementation DestroyerSpaceship
- (instancetype) init {
// note that [super init] will call the SpaceshipNode's init method
if (self = [super init]) {
NSLog(@"A new DestroyerSpaceship was just init'ed.");
// add a body sprite
// SKSpriteNode * body = ...;
// [self addChild:body];
// a Destroyer is much faster than your average spaceship
self.engineThrust = 10.0;
// set class specific variables
self.missileThrust = 5.f;
}
return self;
}
现在,您可以致电:
SpaceshipNode * newSpaceShip = [SpaceshipNode new]; // short for [[SpaceshipNode alloc] init];
DestroyerSpaceship * newDestroyer = [DestroyerSpaceship new];
这两行将记录以下内容。最后两行是由驱逐舰引起的,驱逐舰首先调用SpaceshipNode
init
,然后调用特定于驱逐舰的init
方法。
新的SpaceshipNode刚刚初始化。
新的SpaceshipNode刚刚初始化。
新的DestroyerSpaceship刚刚开始使用。
你甚至可以这样使用它:
SpaceshipNode * newUnidentifiedVessel = [DestroyerSpaceship new];
if ([newUnidentifiedVessel isKindOfClass:[DestroyerSpaceship class]]) {
NSLog(@"We are under attack! Route power to shields!");
}
答案 1 :(得分:0)
- (instancetype)makeDestroyerSpaceship{
if (self = [super baseSpaceshipWithImageNamed:@"DestroyerShip"]) {
self.engineThrust = 2.0;
self.missileThrust = 3.0;
}
return self;
}