Home of Ebyan Alvarez-Buylla

Cocos2d iPhone Repeating Sprite

Cocos2d iPhone Repeating Sprite

Since Cocos2d iPhone’s OpenGL is only capable of repeating textures that have dimensions which are a power of two, I’ve put together a quick-and-dirty algorithm to tile arbitrarily-sized sprites to arbitrary sizes. TiledSprite takes a source sprite with a texture from a file or a subtexture from an atlas, and clips and/or tiles to fit the requested width and height. The source code is available on GitHub as a Gist, just copy-paste it, download it, or clone the repo and grab the .h and .m for use in your project.

The header image was generated with this texture, from The Liberated Pixel Cup:

Brick texture from the Liberated Pixel Cup.

Using the following straightforward code:

CCSprite* sourceSprite = [[CCSprite alloc] initWithFile:@"brick.png"];
sourceSprite.anchorPoint = ccp(0, 0);
sourceSprite.position = ccp(20, 100);
[self addChild:sourceSprite];

TiledSprite* croppedSprite = [[TiledSprite alloc] initWithSprite:sourceSprite width:16 height:16];
croppedSprite.anchorPoint = ccp(0, 0);
croppedSprite.position = ccp(60, 100);
[self addChild:croppedSprite];

TiledSprite* skinnySprite = [[TiledSprite alloc] initWithSprite:sourceSprite width:10 height:50];
skinnySprite.anchorPoint = ccp(0, 0);
skinnySprite.position = ccp(84, 100);
[self addChild:skinnySprite];

TiledSprite* longSprite = [[TiledSprite alloc] initWithSprite:sourceSprite width:100 height:20];
longSprite.anchorPoint = ccp(0, 0);
longSprite.position = ccp(102, 100);
[self addChild:longSprite];

TiledSprite* bigSprite = [[TiledSprite alloc] initWithSprite:sourceSprite width:160 height:120];
bigSprite.anchorPoint = ccp(0, 0);
bigSprite.position = ccp(210, 100);
[self addChild:bigSprite];

The algorithm to draw the tiled sprite is fairly straightforward, as a cursory glance of the source code will reveal. The one bit of headache was fiddling with the coordinate system to tile from the bottom-left, as Cocos2d expects, since texture coordinates (even in Cocos2d) are top-left.

Even though the sample image pictured here happens to coincidentally be an image with dimensions that are a power of two, the algorithm works with source textures or subtextures of any size, since it places sprites manually instead of using OpenGL’s GL_REPEAT.

I release this code as Public Domain. I would love to hear if it has helped you or if you fork it into a properly optimized version, but you are not bound to notify me. 😉 Enjoy!