3

Is there possible to get current image name from SKTexture from SKSpriteNode?

I am a new in SpriteKit and I'm writing a little game. I need to detect when ninja will hit enemy. Something like this

enter image description hereenter image description here

I am doing SKAction like

- (void)setUpHit
{
    SKTextureAtlas *hitAtlas = [SKTextureAtlas atlasNamed:@"Ninja_hit"];

    SKTexture *hit1 = [hitAtlas textureNamed:@"Ninja_hit_1"];
    SKTexture *hit2 = [hitAtlas textureNamed:@"Ninja_hit_2"];
    SKTexture *hit3 = [hitAtlas textureNamed:@"Ninja_hit_3"];
    SKTexture *hit4 = [hitAtlas textureNamed:@"Ninja_hit_4"];

    SKAction *hitAnimation = [SKAction animateWithTextures:@[hit1, hit2, hit3, hit4]
                                              timePerFrame:0.1];

    SKAction *wait = [SKAction waitForDuration:0.3];

    SKAction *goBack = [SKAction animateWithTextures:@[hit1, [SKTexture textureWithImageNamed:@"Ninja"]]
                                        timePerFrame:0.1];

    self.hitAction = [SKAction sequence:@[hitAnimation, wait, goBack]];
}

But hit is going only on images Ninja_hit_2.png or Ninja_hit_3.png.

So I need to detect current texture image name when i am doing intersectsNode ninja with enemy.

Now I am doing something like

if ([ninja intersectsNode:node] &&  !self.isKilled)
{
    SKTexture *currentTexture = [ninja texture];

    if ([self isHit:currentTexture])
    {
        //kill enemy here
    }  
}

where

- (BOOL)isHit:(SKTexture *)texture
{
    NSString *description = [texture description];
    NSRange range = [description rangeOfString:@"'"];
    NSString *textureName = [description substringFromIndex:NSMaxRange(range)];
    range = [textureName rangeOfString:@"'"];
    textureName = [textureName substringToIndex:NSMaxRange(range) - 1];

    if ([textureName isEqualToString:@"Ninja_hit_2.png"] ||
        [textureName isEqualToString:@"Ninja_hit_3.png"])
    {
        return YES;
    }

    return NO;
}

I know that is not correct, but I can't find how to take current texture name or doing it correctly. Could you help me?

4

3 回答 3

3

嗯,我的策略是这样的:

在你的忍者班上,你的纹理有一个属性。让他们留在身边

@property (nonatomic, strong) NSArray * hitTextures;

然后存储命中的纹理(注意这是一个延迟加载的getter方法)

-(NSArray *)hitTextures{
    if (_hitTextures == nil){
        SKTexture *hit1 = [SKTexture textureWithImageNamed:@"Ninja_hit_1"];
        SKTexture *hit2 = [SKTexture textureWithImageNamed:@"Ninja_hit_2"];
        SKTexture *hit3 = [SKTexture textureWithImageNamed:@"Ninja_hit_3"];
        SKTexture *hit4 = [SKTexture textureWithImageNamed:@"Ninja_hit_4"];

        _hitTextures = @[hit1, hit2, hit3, hit4];
    }
    return _hitTextures;
}

请注意,我们不需要SKTextureAtlas显式地创建对象:

加载纹理数据时,Sprite Kit 会在应用程序包中搜索具有指定文件名的图像文件。如果找不到匹配的图像文件,Sprite Kit 会在存储在应用程序包中的任何纹理图集中搜索纹理。如果指定的图像不存在于包中的任何位置,Sprite Kit 会创建一个占位符纹理图像。

使用此纹理数组填充您的SKAction

    SKAction *hitAnimation = [SKAction animateWithTextures:self.hitTextures
                                              timePerFrame:0.1];

这允许您-isHit像这样更改您的方法:

- (BOOL)isHit:(SKTexture *)texture
{
    NSUInteger index = [self.hitTextures indexOfObject:texture];

    if (index == 1 ||
        index == 2)
    {
        return YES;
    }

    return NO;
}

这样,您就不必依赖-description可能会更改的方法的实现细节。

于 2014-02-11T10:39:04.037 回答
3

从 SKAtlas 动画中检测当前名称,这不是最好的方法,但它对我有用。

var tempstr = yoursprite.texture!.description

        if(tempstr.rangeOfString("currentFrameName", options: NSStringCompareOptions.LiteralSearch, range: nil, locale: nil) != nil){
// do something
}
于 2014-11-26T14:13:42.317 回答
1

查看 SKSpriteNode 的纹理描述应该可以看到图像的名称

for node in self.children {
    if node is SKSpriteNode && node.physicsBody != nil  {
        let spriteNode:SKSpriteNode = node as! SKSpriteNode
        print("sprite node image name \(spriteNode.texture!.description)")
    }
}

这样的一个例子将在调试时打印出来

精灵节点图像名称“Clear10x10”(10 x 10)

然后,您可以 RegX 图像名称的第三个字段,在此示例中为“Clear10x10”。请注意,Apple 可能会更改此描述格式。

于 2020-01-01T19:50:05.247 回答