A Poor Man’s SpriteKit Health Bar

I recently needed to display a unit health bar for a SpriteKit game prototype I am working on. Previously, I posted a simple SpriteKit progress bar control, TCProgressBarNode. To achieve a health bar effect, I wanted to change the fill color of the progress bar based on the fill percent.

Using this StackOverflow post as a guide, I created a simple TCProgressBarNode subclass, TCHealthBar, and added a setProgress override:

- (void)setProgress:(CGFloat)progress
    [super setProgress:progress];
    CGFloat hue = MAX(0, ((120.0 * progress) / 360.0) - (20.0/360.0));
    self.fillColor = [UIColor colorWithHue:hue saturation:kHealthBarSaturation brightness:kHealthBarBrightness alpha:1.0];

You’ll notice that I’m skewing the color values a little toward the red side of the spectrum, because I wanted my health bar to turn bright red sooner. The results came out pretty well for a quick health bar:

I hope this will give you all some ideas about how you can use TCProgressBarNode to create health bars in your own SpriteKit games.

Thanks for reading!

TCProgressTimer – Revisited

A while ago, I posted a SpriteKit equivalent to CCProgressTimer, TCProgressTimer. Recently I had a need for a progress timer for prototyping, but I didn’t want to be forced to provide textures. To fit this need, I’ve revisited TCProgressTimer and added a method for creating simple progress timers using a radius and a set of colors:

- (instancetype)initWithRadius:(CGFloat)radius
               backgroundColor:(UIColor *)backgroundColor
               foregroundColor:(UIColor *)foregroundColor;

This allows me to get a simple progress timer up and running quickly, without having to worry about artwork. Here’s the new, simple flavor of the timer in action in the demo project:


Along the way, I also modernized the interface a bit. Instead of calling setProgress:, progress is now a property on the timer object.

Source Code

You can download the source code here.

CAShapeLayer FTW! Cheers.


Today, I give you a follow up to my original TCProgressBarNode. I needed a progress bar with discrete segments, so I created a subclass of TCProgressBarNode. Like the original, you can get a simple progress bar up and going very easily. I also included a property on the control (filledSegments) which allows you to fill segments rather than setting progress as a percentage of the whole.

Here’s the bar in action:


Source Code

You can download the source code here.

Thanks for reading, and enjoy!

TCProgressBarNode – A SpriteKit progress bar

Recently, I had a need for a SpriteKit progress bar. I found a few third party controls, but they all used an architecture that required me to create a set of textures for each frame of the progress bar. Creating a different image for each frame of a progress bar seemed unnecessary for me, especially during a prototyping phase. What I wanted was a progress bar control that was easy to add during the prototyping phase but flexible enough to be customized as needed for a production ready project. And thus – TCProgressBarNode was born.


TCProgressBarNode can be initialized in one of two ways. First, for more simple progress bars, you can initialize the control with a set of colors and sizes to get a quick progress bar.

- (instancetype)initWithSize:(CGSize)size
             backgroundColor:(UIColor *)backgroundColor
                   fillColor:(UIColor *)fillColor
                 borderColor:(UIColor *)borderColor

With this flavor of initializer, you get a nice simple progress bar.


Alternatively, if you want to customize the progress bar beyond colors and sizes, you can also provide your own textures to the control.

- (instancetype)initWithBackgroundTexture:(SKTexture *)backgroundTexture
                              fillTexture:(SKTexture *)fillTexture
                           overlayTexture:(SKTexture *)overlayTexture;

Once you have initialized the control and added it to your scene, setting progress is simple.

self.progressBarNode.progress = 0.5f;

This simple control was more than enough for my prototyping needs. You should be able to use this as a good starting point for progress bars in your own games.

Source Code

You can download the source code here.

Thanks for reading, and enjoy!

TCProgressTimer – A SpriteKit progress timer

Hello all.  For my first legit blog post, I’d like to share a very basic progress timer I made while messing around with SpriteKit.  It’s very similar to CCProgressTimer if you’ve ever used cocos2d.

In this prototype game, the player must position her units appropriately to successfully defend against waves of creeps and prevent them from reaching the end of a path. I created a nice wave indicator node that shows how long it will take for the next wave of creeps to arrive on the map.  The wave indicator node’s background is gray and slowly fills with an orange color.  You can see the wave indicator in this screenshot from a prototype of the game:


I decided to pack up the progress timer into an open source demo project so that you all could modify it for usage in your own SpriteKit games.  The progress timer object is named TCProgressTimer.


Usage of TCProgressTimer is simple. Initialize the object using one of the two initializers

- (id)initWithForegroundImageNamed:(NSString *)foregroundImageName
              backgroundImageNamed:(NSString *)backgroundImageName
               accessoryImageNamed:(NSString *)accessoryImageName;

- (id)initWithForegroundTexture:(SKTexture *)foregroundTexture
              backgroundTexture:(SKTexture *)backgroundTexture
               accessoryTexture:(SKTexture *)accessoryTexture;

The background and accessory parameters are optional – you can pass nil if you don’t need a background or an accessory view on the progress timer.  Once initialized, just throw the progress timer into your scene somewhere and use the setProgress: method to set the fill percentage (a value from 0.0 to 1.0).


The implementation is pretty simple as well.  TCProgressTimer is a SKSpriteNode subclass which  has three layers:  a background texture, a foreground texture, and an accessory texture.

@interface TCProgressTimerNode ()

@property (nonatomic, strong) SKSpriteNode *backgroundImageSpriteNode;
@property (nonatomic, strong) TCProgressTimerForegroundCropNode *foregroundCropNode;
@property (nonatomic, strong) SKSpriteNode *accessorySpriteNode;


The background and accessory nodes are nothing special.  The magic lies in the TCProgressTimerForegroundCropNode that is sandwiched between the two.  TCProgressTimerForegroundCropNode is an SKCropNode subclass that consists of a SKSpriteNode and an SKShapeNode that is used as a mask.

@interface TCProgressTimerForegroundCropNode ()

@property (nonatomic, strong) SKSpriteNode *indicatorSpriteNode;
@property (nonatomic, strong) SKShapeNode *maskShapeNode;


All the magic is in two methods:

- (void)initializeMaskShapeNode
    _maskShapeNode = [SKShapeNode node];
    _maskShapeNode.antialiased = NO;
    _maskShapeNode.lineWidth = _indicatorSpriteNode.texture.size.width;

    self.maskNode = _maskShapeNode;

- (void)setProgress:(CGFloat)progress
    progress = 1.0f - progress;

    CGFloat startAngle = M_PI / 2.0f;
    CGFloat endAngle = startAngle + (progress * 2.0f * M_PI);

    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointZero
    self.maskShapeNode.path = path.CGPath;

The SKShapeNode is initialized, given a lineWidth equal to the width of the texture provided upon initialization, and assigned as a mask node. Later, when setProgress: is called, a UIBezierPath is generated using bezierPathWithArcCenter: and the newly generated path is applied to the mask node. That’s really all there is to it!

Here’s a shot from the demo showing three versions of the progress timer. The first uses the foreground image only. The second adds a background image. And the third adds the accessory image.


Source Code

I probably won’t be touching the progress timer much more because this basic implementation fit my prototyping needs.  I’ve posted the complete source code wrapped up in a demo project on BitBucket.

You can download the source code here.

Note:  At the time of this writing, SKShapeNode appears to leak a small amount of memory.  Several other developers in the Apple dev forums have reported having the same leak with SKShapeNode.  Hopefully we will get a fix soon!

Also Note: Since writing this, I’ve discovered that SKShapeNode really sucks. I wouldn’t recommend anyone use SKShapeNode for anything other than prototyping. For alternative approaches, see the source code for my new control, TCProgressBarNode.

Thanks for reading!