9-Patch technique in Cocos2D

Note: This post belongs to a long series whose summary is here and which aims to present you how to use the CCControl  library.

It often happens that we need to stretch images with no predefined sizes, as for example with buttons whose size adapts to the title or likewise to the background of the pop-up which has to be adapted to its content. A problem occurs when you work with images having rounded corners for example because when you stretch it the corners are deformed and the result is not really good.

One way to avoid this problem in computer science is to use the 9-Patch technique. This post aims to explain you what is it and how it works by using the CCScale9Sprite class which is based on this principle.

9-Patch Sprite

A 9-Patch sprite is a small image which defines the stretchable/repeatable and the static areas thanks to a grid as shown below:

CCScale9Sprite

As you can see, with the 9-Patch you set a 3×3 grid (here of the same size) which defines how each zone can be stretchable (or fix for the corners). When you need to re-size your sprite the corners will stay exactly the same, and there are only the stretchable areas which will fit the to the new given space. The following scheme illustrates this:

Scale9-Work

A simple example would be if you were to take a rounded button (like the rounded UIButton’ skin) and make it adaptable to its title. The four corners wouldn’t change sizes at all but would be static, while the other areas would be stretched or repeated to allow the whole image to scale appropriately to its content. Here you could put the title text inside the center area and just stretch the 9-Patch image to fit it.

Now we are going to see how this technique is used with our library and how it works.

CCScale9Sprite

The CCScale9Sprite is an implementation of the 9-Patch principle for Cocos2D and the CCControl extension. This class allows you to define a cap which define the portions of the sprite that should be stretched:

CCScale9Sprite

The cap is defined by a rectangle when you initialize the CCScalse9Sprite, and if no cap is defined the default behavior is to divide the sprite into a 3×3 grid with squares of the same size:

CCScale9Sprite *mysprite = [CCScale9Sprite spriteWithFile:@"CCControlButton.png" capInsets:CGRectMake(12, 12, 56, 56)];

// Change the content size of the sprite and it'll be stretch automatically
[mysprite setContentSize:CGSizeMake(299, 134)];

In this example, we have defined the cap in such a way that the corners must not be re-sized. The left and right sides will stretch in the height direction only while the top and bottom sides will be re-sized only in the width direction, and the center will be stretched both in the height and the width direction.

Where To Go From Here?

As seen previously, the 9-Patch technique is very useful when you need to dynamically re-size background elements like with popups, buttons or others. Indeed, with a tiny sprite we can create elements with a background that fit correctly (without deformations) to its content simply by defining the areas that are fixed and the other ones  that can be stretched. The main advantage of this technique is that with only one sprite you can have a infinite of possibility.

Into the CCControlExtension, the CCScale9Sprite is mainly used with the CCControlButton. However don’t hesitate to play with it with your  own projects/components.

You can find the code source and the examples on github and the API documentation hosted here.

If you have any questions or comments, put them below. 🙂

1 Star2 Stars3 Stars4 Stars5 Stars (8 votes, average: 4.50 out of 5)
Loading...

0 comments

Time limit is exhausted. Please reload CAPTCHA.

This site uses Akismet to reduce spam. Learn how your comment data is processed.