2014-02-11 82 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