如何在Sprite Kit中设置纹理到tile

时间:2013-11-13 20:19:35

标签: ios objective-c sprite-kit

我正在制作一个精灵工具包游戏,显然有一个带有平铺纹理的大型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中实现纹理的平铺效果,而不会创建非常大的图像。

这是我的问题的图像: enter image description here

6 个答案:

答案 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)

此解决方案允许使用在资产编辑器中完成的切片,这确实很棒。