【问题标题】: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 在游戏场景中被声明是的

标签: ios objective-c sprite-kit init skspritenode


【解决方案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
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 2021-03-23
  • 2017-06-29
  • 2017-12-19
  • 2018-11-24
  • 2015-10-21
相关资源
最近更新 更多