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?

有帮助吗?

解决方案

Hmm my strategy would be this:

On your ninja class have a property for your textures. Keep them around

@property (nonatomic, strong) NSArray * hitTextures;

Then store the hit textures (note this is a lazy loading getter method)

-(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;
}

Note that we don't need to make the SKTextureAtlas object explicitly:

When loading the texture data, Sprite Kit searches the app bundle for an image file with the specified filename. If a matching image file cannot be found, Sprite Kit searches for the texture in any texture atlases stored in the app bundle. If the specified image does not exist anywhere in the bundle, Sprite Kit creates a placeholder texture image.

Use this texture array to fill in your SKAction

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

This allows you do change your -isHit method like so:

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

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

    return NO;
}

This way you don't rely on an implementation detail of the -description method that is subject to change.

其他提示

to detect the current name out of a SKAtlas Animation, this is not the best way but it works for me.

var tempstr = yoursprite.texture!.description

        if(tempstr.rangeOfString("currentFrameName", options: NSStringCompareOptions.LiteralSearch, range: nil, locale: nil) != nil){
// do something
}

Look at the texture description of the SKSpriteNode and you should be able to see the name of the image

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)")
    }
}

an example of this will print out on debug

sprite node image name 'Clear10x10' (10 x 10)

You can then RegX the third field for the image name, 'Clear10x10' in this example. Note that Apple may change this description format.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top