Search code examples
animationios7sprite-kitskcropnode

Animate masked image in SpriteKit (SKCropNode)


I'm using Sprite Kit to create my first iOS app, and I'm stumbling over what seems to be a pretty basic problem.

I'm trying to animate the contents (fillNode) of a SKCropNode (cropNode). The code below sets up the SKScene just fine (I see the illustration masked correctly, placed over the background image in the right location)...

SKSpriteNode *logoBG = [[SKSpriteNode alloc] initWithImageNamed:logoBackground];
logoBG.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self addChild:logoBG];

SKCropNode *cropNode = [[SKCropNode alloc] init];
cropNode.maskNode = [[SKSpriteNode alloc] initWithImageNamed:logoMask];
SKSpriteNode *fillNode = [[SKSpriteNode alloc] initWithImageNamed:logoImage];

[cropNode addChild:fillNode];
fillNode.position = CGPointMake(0,300);
cropNode.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
self.logoContent = cropNode;
[self addChild:self.logoContent];

...but I can't access the masked illustration to animate its position (I want it to start off outside the mask and slide into position):

CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;

SKAction *moveUp = [SKAction moveByX: 0 y: 100 duration: 5];
SKAction *moveSequence = [SKAction sequence:@[moveUp]];
[self.logoContent.target_illustration runAction: moveSequence completion:^{ // '.target_illustration' = the SKSpriteNode that I want to animate; cropNode.fillNode
    SKScene *titleScreen  = [[TitleScreen alloc] initWithSize:self.size];
    SKTransition *fade = [SKTransition fadeWithDuration:(1)];
    [self.view presentScene:titleScreen transition:fade];
}];

I can only animate the whole logoContent rather than its child nodes.

Any ideas where I'm going wrong?


Solution

  • Just for reference if anyone wants to know how to mask, here is a simple snippet

    - (void) cropNodes
    {
        // the parent node i will add to screen
        SKSpriteNode *picFrame = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(100, 100)];
        picFrame.position = CGPointMake(200, 200);
    
        // the part I want to run action on
        SKSpriteNode *pic = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
        pic.name = @"PictureNode";
    
        SKSpriteNode *mask = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(80, 50)];
    
        SKCropNode *cropNode = [SKCropNode node];
        [cropNode addChild:pic];
        [cropNode setMaskNode:mask];
        [picFrame addChild:cropNode];
        [self addChild:picFrame];
    
        // run action in this scope
            //[pic runAction:[SKAction moveBy:CGVectorMake(30, 30) duration:10]];
    
        // outside scope - pass its parent
       [self moveTheThing:cropNode];
    }
    
    - (void) moveTheThing:(SKNode *) theParent
    {
        // the child i want to move
        SKSpriteNode *moveThisThing = (SKSpriteNode *)[theParent   childNodeWithName:@"PictureNode"];
        [moveThisThing runAction:[SKAction moveBy:CGVectorMake(30, 30) duration:10]];
    }