Reputation: 471
Using SpriteKit, how would I tile a SKTexture that repeats itself horizontally to fill the width of the SKSpriteNode? This is what I have so far - only stretches the texture.
var header = SKSpriteNode()
let headerTexture = SKTexture(imageNamed: "inGameHeader-1.png")
header = SKSpriteNode(texture: headerTexture)
header.position = CGPoint(x: 0, y: CGRectGetMaxY(self.frame)-39)
header.size.width = CGRectGetWidth(self.frame)
header.size.height = 150
header.anchorPoint = CGPoint(x: 0,y: 1)
addChild(header)
Upvotes: 5
Views: 1850
Reputation: 473
Here's a static function for Swift 3 and 4. Not using an extension as the SKTexture class doesn't actually have a designated initializer.
Note this won't be very performant. Best to preload the texture before use, or dive into the world of custom Shaders.
static func generateTiledTexture(size: CGSize, imageNamed imageName: String) -> SKTexture? {
var texture: SKTexture?
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()
if let image = UIImage(named: imageName), let cgImage = image.cgImage {
context?.draw(cgImage, in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height), byTiling: true)
if let tiledImage = UIGraphicsGetImageFromCurrentImageContext() {
texture = SKTexture(image: tiledImage)
}
}
UIGraphicsEndImageContext()
return texture
}
Upvotes: 1
Reputation: 11
you know you can do this in UIButton or UIImageView by resizableImageWithCapInsets ,so ,Here is my solution :
-(SKTexture *)textureWithImage:(UIImage *)image tiledForSize:(CGSize)size withCapInsets:(UIEdgeInsets)capInsets{
//get resizable image
image = [image resizableImageWithCapInsets:capInsets];
//redraw image to target size
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f);
[image drawInRect:CGRectMake(0, 0, size.width-1, size.height-1)];
[[UIColor clearColor] setFill];
//get target image
UIImage *ResultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// get texture
SKTexture * texture = [SKTexture textureWithImage:ResultImage];
return texture;
}
Upvotes: 0
Reputation: 1355
Here is my solution : Send your image to this function, with the size of the sprite, followed by the size of the tile. This will return a tiled SKTexture.
-(SKTexture *)tiledTextureImage:(UIImage *)image ForSize:(CGSize)size tileSize:(CGSize)tileSize{
// First we create a new size based on the longest side of your rect
int targetDimension = (int)fmax(size.width,size.height);
CGSize targetSize = CGSizeMake(targetDimension, targetDimension);
// Create a CGImage from the input image and start a new image context.
struct CGImage *targetRef = image.CGImage;
UIGraphicsBeginImageContext(targetSize);
CGContextRef contextRef = UIGraphicsGetCurrentContext();
// Now we simply draw a tiled image
CGContextDrawTiledImage(contextRef, CGRectMake(0,0, tileSize.width,tileSize.height), targetRef);
UIImage *tiledTexture = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Finally create a texture and return it.
return [SKTexture textureWithImage:tiledTexture];
}
Upvotes: 1