Search code examples
iossprite-kitprogress-bar

How to create progress bar in sprite kit?


I want to create my own progress bar in Sprite Kit.
I figured I will need to images - one fully empty progress bar and filled progress bar.
I have those images, I put filled one on top of empty one, they are regular SKSPriteNodes now I can't figure out how do I cut my filled image where I need?

How do I cut SKSpriteNode image at certain point? Maybe texture?


Solution

  • I would recommend looking into SKCropNode. For a visual aid how SKCropNode works, look it up in the Apple Programming Guide. I have read through the entire document multiple times and it is a particularly good read.

    SKCropNode is basically an SKNode which you add to your scene, but its children can be cropped by a mask. This mask is set in the maskNode property of the SKCropNode. In this way, you only need one texture image. I would subclass SKCropNode to implement functionality to move or resize the mask, so you can easily update its appearance.

    @interface CustomProgressBar : SKCropNode
    
    /// Set to a value between 0.0 and 1.0.
    - (void) setProgress:(CGFloat) progress;
    
    @end
    
    @implementation CustomProgressBar
    
    - (id)init {
      if (self = [super init]) {
        self.maskNode = [SKSpriteNode spriteNodeWithColor:[SKColor whiteColor] size:CGSizeMake(300,20)];
        SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"progressBarImage"];
        [self addChild:sprite];
      }
      return self;
    }
    
    - (void) setProgress:(CGFloat) progress {
      self.maskNode.xScale = progress;
    }
    
    @end
    

    In your scene:

    #import "CustomProgressBar.h"
    
    // ...
    
    CustomProgressBar * progressBar = [CustomProgressBar new];
    [self addChild:progressBar];
    
    // ...
    
    [progressBar setProgress:0.3];
    
    // ...
    
    [progressBar setProgress:0.7];
    

    Note: this code doesn't move the mask (so the sprite will be cropped on either side) but I'm sure you get the idea.