初始化子类不起作用

Posted

技术标签:

【中文标题】初始化子类不起作用【英文标题】:Init subclass does not work 【发布时间】:2015-09-09 15:16:21 【问题描述】:

我想通过子类生成精灵节点以进行屏幕显示,但它没有显示在屏幕上。有人知道我做错了什么吗?

子类

@implementation Seagull

-(id)init

    self = [super init];
    if (self) 
        _atlas = [SKTextureAtlas atlasNamed:@"Seagull"];
        _seagull = [SKSpriteNode spriteNodeWithTexture:[_atlas textureNamed:@"Seagull1"]];
        _seagull.size = CGSizeMake(156.8, 115.4);

        NSArray *flyFrames = @[[_atlas textureNamed:@"Seagull1"],
                               [_atlas textureNamed:@"Seagull2"]];

        _flyAnimation = [SKAction repeatActionForever:[SKAction animateWithTextures:flyFrames timePerFrame:0.15 resize:NO restore:NO]];

        [_seagull runAction:_flyAnimation];
    
    return self;


@end

已创建子类对象

-(Seagull *)spawnSeagull

    Seagull *seaGull = [[Seagull alloc] init];
    seaGull.position = CGPointMake(self.size.width * 0.5, self.size.height * 0.5);
    NSLog(@"seagull postion.x = %f && position.y = %f", seaGull.position.x, seaGull.position.y);
    [self addChild:seaGull];

    return seaGull;

在 viewDidLoad 中添加到场景中

[self spawnSeagull];

【问题讨论】:

您在spawnSeagull 中返回了一只海鸥,但您没有表明它被分配给[self spawnSeagull]; 中的任何对象。你的意思是写_seagull = [self spawnSeagull]; 您的代码是否出错?因为我猜在您的 GameScene 中,没有声明名为 spawnSeagull 的方法。 @timgcarlson 嗯。没有分配给任何对象是什么意思?我是否需要在 GameScene 中创建一个 SKSpriteNode 对象并将其分配给 spawnSeagull 或 Didmovetoview 中的 Seagull 类对象? @WangYudong spawnSeagull 在游戏场景中被声明是的 【参考方案1】:

您在 SKSpriteNode (Seagull) 中创建属性 SKSpriteNode (_seagull) 时犯了一个错误。

在您的init 方法中,您将_seagull 初始化为SKSpriteNode,但是当生成海鸥时,您所做的只是创建类Seagull 的实例并将其添加到场景中,与_seagull 实际上包含海鸥的纹理。要解决这个问题,您需要在 spawnSeagull 中返回 seaGull.seagull,这恐怕不是最佳做法。

但是,您的代码中仍有几个地方需要修复。

spawnSeagull:

CGPointMake(self.size.width * 0.5, self.size.height * 0.5) 是错误的,因为这样你不会得到一半大小的场景。 您应该在 GameScene 中调用 [self addChild:seaGull],因为您想将其添加到场景中,而不是添加到 SKSpriteNode 的子类中。

viewDidLoad(推荐didMoveToView):

正如@timgcarlson 所说,您需要一个对象来为其分配spawnSeagull 的返回结果。

我在下面添加完整的代码:

去掉init,在子类中添加类方法,

+ (Seagull *)spawnSeagull

    SKTextureAtlas *atlas = [SKTextureAtlas atlasNamed:@"Seagull"];
    Seagull *seagull = [Seagull spriteNodeWithTexture:[atlas textureNamed:@"Seagull1"]];

    // seagull.size = CGSizeMake(156.8, 115.4);
    // May be set scale of seagull is better? like:
    seagull.scale = 2.0;

    NSArray *flyFrames = @[[atlas textureNamed:@"Seagull1"],
                           [atlas textureNamed:@"Seagull2"]];
    SKAction *flyAnimation = [SKAction repeatActionForever:[SKAction animateWithTextures:flyFrames timePerFrame:0.15 resize:NO restore:NO]];

    [seagull runAction:flyAnimation];

    return seagull;

调用GameScene中的类方法,

- (void)didMoveToView:(SKView *)view

    Seagull *seagull = [Seagull spawnSeagull];
    seagull.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
    [self addChild:seagull];

在this Apple doc 中查找更多示例代码,它如何创建shipSprite 会有所帮助。

【讨论】:

感谢您的明确回复@WangYudong!但是,你什么时候使用 init? @Nielsapp 在spawnSeagull 中,spriteNodeWithTexture 实际上是为您工作的init,所以这里不需要使用init

以上是关于初始化子类不起作用的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionViewFlowLayout 子类不起作用

UIButton 子类@IBAction 不起作用

ManagedObjectModel 子类在 Swift 中不起作用

安全区域在自定义 TabBarController 的 ViewController 中不起作用

用子类填充的基类向量不起作用

以编程方式创建的 UIControl 中的 AutoLayout 似乎不起作用