2014-02-11 57 views
26

有没有办法让一个SKSpriteNode回合?我正在尝试创建一个填充颜色为SkSpriteNode的Tile likesqaure块:SKSpriteNode - 创建一个圆角节点?

SKSpriteNode *tile = [SKSpriteNode spriteNodeWithColor:[UIColor colorWithRed:0.0/255.0 
                      green:128.0/255.0 
                      blue:255.0/255.0 
                      alpha:1.0] size:CGSizeMake(30, 30)]; 

我该如何使它圆角?

谢谢!

+1

**注**你可能会更好,只是使图像具有透明的角落 - https://stackoverflow.com/a/39983382/294884 – Fattie

回答

43

要获得圆角节点,您可以使用2种方法,每种方法都需要使用SKShapeNode。

第一种方式是使用SKShapeNode并设置其路径为圆角矩形这样的:

SKShapeNode* tile = [SKShapeNode node]; 
[tile setPath:CGPathCreateWithRoundedRect(CGRectMake(-15, -15, 30, 30), 4, 4, nil)]; 
tile.strokeColor = tile.fillColor = [UIColor colorWithRed:0.0/255.0 
                green:128.0/255.0 
                blue:255.0/255.0 
                alpha:1.0]; 

另一种使用精灵节点,作物节点和SKShapeNode与圆角矩形作为作物节点掩模:

SKSpriteNode *tile = [SKSpriteNode spriteNodeWithColor:[UIColor colorWithRed:0.0/255.0 
                      green:128.0/255.0 
                      blue:255.0/255.0 
                      alpha:1.0] size:CGSizeMake(30, 30)]; 
SKCropNode* cropNode = [SKCropNode node]; 
SKShapeNode* mask = [SKShapeNode node]; 
[mask setPath:CGPathCreateWithRoundedRect(CGRectMake(-15, -15, 30, 30), 4, 4, nil)]; 
[mask setFillColor:[SKColor whiteColor]]; 
[cropNode setMaskNode:mask]; 
[cropNode addChild:tile]; 

如果你的瓷砖是一种纯色,我建议你去第一种方法。

+0

即使在SKShapeNode目前存在不一致的情况下,第一种方法似乎很可靠,而且实施起来相当简单。 – Toby

+7

SKShapeNode现在有一个'rectOfSize :, cornerRadius:'初始化程序 –

+0

如果你的图块使用了纹理,你仍然可以用第一种方法,通过设置SKShapeNode的fillTexture。 –

0

从类参考:

“一个SKSpriteNode是绘制有纹理的图象,彩色方形,或具有颜色混合有纹理的图象的节点”

看来最简单的方法是画一个块带有圆角,然后使用这些类的方法之一:

  • spriteNodeWithImageNamed:
  • spriteNodeWithTexture:
  • spriteNodeWithTexture:尺寸:
+5

+1:Sprite Kit不是绘图API。它是管理预定义像素块(又名精灵)运动的引擎。 – rickster

5

希望这有助于:

SKSpriteNode *make_rounded_rectangle(UIColor *color, CGSize size, float radius) 
{ 
    UIGraphicsBeginImageContext(size); 
    [color setFill]; 
    CGRect rect = CGRectMake(0, 0, size.width, size.height); 
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius]; 
    [path fill]; 
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    SKTexture *texture = [SKTexture textureWithImage:image]; 
    return [SKSpriteNode spriteNodeWithTexture:texture]; 
} 
3

这在很大程度上受到公认的答案的启发,但它采用了更加易读的方式来创建SKShapeNode和还修复周围作物恼人的像素线。看起来像一个小细节,但它可能花费几分钟的时间。

CGFloat cornerRadius = 15; 
SKCropNode *cropNode = [SKCropNode node]; 
SKShapeNode *maskNode = [SKShapeNode shapeNodeWithRectOfSize:scoreNode.size cornerRadius:cornerRadius]; 
[maskNode setLineWidth:0.0]; 
[maskNode setFillColor:[UIColor whiteColor]]; 
[cropNode setMaskNode:maskNode]; 
[cropNode addChild:scoreNode]; 
+0

对不起,重复我自己,但老实说,为了这里的任何人搜索,你只是不这样做!你只是裁剪PNG,就是这么简单 – Fattie

+0

@Fattie我的答案是一般的,并且裁剪任何节点。我没有使用PNG,如果我使用了,我肯定不会想要触碰它们中的每一个。所以它仍然有其价值。 –

11

在斯威夫特3,你可以创建:

let tile = SKShapeNode(rect: CGRect(x: 0, y: 0, width: 30, height: 30), cornerRadius: 10) 
+0

我应该如何设置这个SKShapeNode的物理体? – iGetIt

0

这里的斯威夫特3片断基于公认的答案的第二个解决方案。

func createPlayerRoundedNode(){ 
    let tile = SKSpriteNode(color: .white, size: CGSize(width: 30, height: 30)) 
    tile.zPosition = 3 
    tile.name = "tile node" 
    let cropNode = SKCropNode() 
    cropNode.zPosition = 2 
    cropNode.name = "crop node" 
    let mask = SKShapeNode(rect: CGRect(x: 0, y: 0, width: 30, height: 30), cornerRadius: 10) 
    mask.fillColor = SKColor.darkGray 
    mask.zPosition = 2 
    mask.name = "mask node" 
    cropNode.maskNode = mask 
    self.addChild(cropNode) 
    cropNode.addChild(tile) 
} 
2

这真是这个简单.......

class YourSprite: SKSpriteNode { 

    func yourSetupFunction() { 

      texture = SKTexture(image: UIImage(named: "cat")!.circleMasked!) 

没有什么更多的东西。

你真的不能使用 SKShapeNode。

就是这么简单。这是一个使用SKShapeNode的疯狂性能,它不是正确的解决方案,它毫无意义的困难,SKShapeNode的目的与这个问题没有任何关系。

enter image description here

看看所有这些小猫!

为circleMasked的代码是这样的简单:

(即用图像处理所有项目都需要这个呢。)

extension UIImage { 

    var isPortrait: Bool { return size.height > size.width } 
    var isLandscape: Bool { return size.width > size.height } 
    var breadth:  CGFloat { return min(size.width, size.height) } 
    var breadthSize: CGSize { return CGSize(width: breadth, height: breadth) } 
    var breadthRect: CGRect { return CGRect(origin: .zero, size: breadthSize) } 

    var circleMasked: UIImage? { 

     UIGraphicsBeginImageContextWithOptions(breadthSize, false, scale) 
     defer { UIGraphicsEndImageContext() } 

     guard let cgImage = cgImage?.cropping(to: CGRect(origin: 
      CGPoint(
       x: isLandscape ? floor((size.width - size.height)/2) : 0, 
       y: isPortrait ? floor((size.height - size.width)/2) : 0), 
      size: breadthSize)) 
     else { return nil } 

     UIBezierPath(ovalIn: breadthRect).addClip() 
     UIImage(cgImage: cgImage, scale: 1, orientation: imageOrientation) 
      .draw(in: breadthRect) 
     return UIGraphicsGetImageFromCurrentImageContext() 
    } 

// classic 'circleMasked' stackoverflow fragment 
// courtesy Leo Dabius /a/29047372/294884 
} 

这一切就是这么简单。

+2

最佳答案!!! – Krunal

+0

尽管这确实圆了,而且好像你已经穿过一系列玻璃墙来找到这个解决方案,这是如何帮助将圆角矩形作为蒙版的? – Confused

+0

hi @Confused。我完全不知道你的意思?你能解释你在问什么 - 我会尽力帮忙。 – Fattie