我正在制作一个精灵工具包游戏,显然有一个带有平铺纹理的大型SKSpriteNode比使用具有平铺纹理的多个SKSpriteNode更有效。我的问题是,当我尝试使用
制作5x5瓷砖时SKTexture* tex = [SKTexture textureWithRect:CGRectMake(0,0,5,5) inTexture:[SKTexture textureWithImageNamed:@"tile.png"]];
SKSpriteNode* node = [SKSpriteNode spriteNodeWithTexture:tex size:CGSizeMake(100,100)];
图像的大小适当,但是它被夹紧而不是平铺。在openGL术语中,我得到一个GL_CLAMP_TO_EDGE,我想要一个GL_REPEAT。无论如何,我可以在单个SKSpriteNode中实现纹理的平铺效果,而不会创建非常大的图像。
这是我的问题的图像:
答案 0 :(得分:10)
Afaik,没有办法用平铺纹理创建精灵。但你可以做的,是在一次绘画过程中渲染很多精灵。
来自Apple的documentation(精灵套件最佳做法 - >绘制内容):
如果节点的所有子节点使用相同的混合模式和纹理 atlas,然后Sprite Kit通常可以在单个中绘制这些精灵 画通。另一方面,如果孩子们这样组织起来的话 每个新精灵的绘图模式都会改变,然后是Sprite Kit 每个精灵执行一次绘图传递,这是非常低效的。
答案 1 :(得分:1)
当使用ciaffinetile过滤器时 创造纹理。
答案 2 :(得分:1)
SKTexture* tex = [SKTexture textureWithRect:CGRectMake(0,0,5,5) inTexture:[SKTexture textureWithImageNamed:@"tile.png"]];
textureWithRect:inTexture:
创建一个子纹理,矩形参数位于单位坐标空间,这意味着所有值都是0-1
CGRectMake(0,0,5,5)
的行为未定义,但似乎将纹理拉伸了5倍。
修改:单位坐标空间
您可以将单位坐标视为指定总可能值的百分比。单位坐标空间中的每个坐标的范围都为0.0到1.0。例如,沿x轴,左边缘位于坐标0.0,右边缘位于坐标1.0。沿y轴,单位坐标值的方向根据平台而变化
Core Animation Programming Guide, Layers Use Two Types of Coordinate Systems
答案 3 :(得分:1)
我发现问题没有得到完美答案。我这样解决了。
你知道你可以通过resizableImageWithCapInsets在UIButton或UIImageView中执行此操作,因此,这是我的解决方案:
-(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;
}
答案 4 :(得分:0)
为了帮助我转换坐标系,我使用以下函数 - 这样我就可以像上面用(5,5)那样使用绝对坐标:
CREATE FUNCTION chart_data (start_idx integer, end_idx integer) RETURNS json AS $$
DECLARE
json_data json;
BEGIN
SELECT json_build_object('data', arr) INTO json_data
FROM (
SELECT json_agg(coalesce(feed.value, -1)) AS arr
FROM generate_series(start_idx, end_idx) i(x)
LEFT JOIN feed ON feed."index" = i.x) sub;
-- Data has been read, so now it can be deleted
DELETE FROM feed
WHERE "index" BETWEEN start_idx AND end_idx;
RETURN json_data;
END;
$ LANGUAGE plpgsql VOLATILE STRICT;
答案 5 :(得分:0)
我使用了薛永伟的答案,并将其扩展为Swift:
extension SKTexture {
static func x_repeatableTexture(named name: String, toSize size: CGSize) -> SKTexture {
let image = UIImage(named: name)
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
image?.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
guard let resultImage = UIGraphicsGetImageFromCurrentImageContext() else {
fatalError("Image could not be drawn.")
}
UIGraphicsEndImageContext()
return SKTexture(image: resultImage)
}
}
您可以通过以下方式使用它:
let texture = SKTexture.x_repeatableTexture(named: textureName, toSize: size)
此解决方案允许使用在资产编辑器中完成的切片,这确实很棒。