2013-11-26 87 views
10

我正試圖在Sprite Kit項目中創建一個圓形遮罩。我創建這樣的圓圈(在屏幕的中心定位的話):Sprite Kit中是否可以使用圓形(SKShapeNode)作爲遮罩?

SKCropNode *cropNode = [[SKCropNode alloc] init]; 

SKShapeNode *circleMask = [[SKShapeNode alloc ]init]; 
CGMutablePathRef circle = CGPathCreateMutable(); 
CGPathAddArc(circle, NULL, CGRectGetMidX(self.frame), CGRectGetMidY(self.frame), 50, 0, M_PI*2, YES); 
circleMask.path = circle; 
circleMask.lineWidth = 0; 
circleMask.fillColor = [SKColor blueColor]; 
[email protected]"circleMask"; 

進一步回落的代碼,我將其設置爲掩碼cropNode

[cropNode setMaskNode:circleMask]; 

...但不是圓圈內顯示的內容,掩碼顯示爲正方形。

是否可以使用SKShapeNode作爲蒙版,還是我需要使用圖像?

回答

12

經過大肆吹噓,在網上衝刷,並在Xcode中進行實驗後,我有一個非常冒險的修復。

請記住,這是一個非常討厭的黑客 - 但你可以指責Sprite Kit的執行SKShapeNode。添加填充到路徑造成以下結果:

  • 添加一個額外的節點到場景
  • 路徑變得不可屏蔽 - 它出現「過度」面具
  • 使得任何非SKSpriteNode兄弟節點不可屏蔽(例如SKLabelNode s)

不是理想狀態。

通過Tony Chamblee's progress timer的啓發,「修復」是完全與填充分配,只是使用路徑的行程:

SKCropNode *cropNode = [[SKCropNode alloc] init]; 

SKShapeNode *circleMask = [[SKShapeNode alloc ]init]; 
CGMutablePathRef circle = CGPathCreateMutable(); 
CGPathAddArc(circle, NULL, CGRectGetMidX(self.frame), CGRectGetMidY(self.frame), 50, 0, M_PI*2, YES); // replace 50 with HALF the desired radius of the circle 
circleMask.path = circle; 
circleMask.lineWidth = 100; // replace 100 with DOUBLE the desired radius of the circle 
circleMask.strokeColor = [SKColor whiteColor]; 
[email protected]"circleMask"; 

[cropNode setMaskNode:circleMask]; 

至於評論,你需要設置半徑的你一半通常有,線寬加倍半徑。

希望蘋果未來會着眼於此;現在,這個黑客是我找到的最好的解決方案(除了使用圖像,如果你的面具需要動態的話,這並不是真的有效)。

5

是的,在當前的Sprite-Kit實現中不可能使用填充顏色的shapenode。我認爲這是一個錯誤。

但是!

您始終可以將形狀渲染爲紋理並將其用作蒙板!

對於前,讓邊緣是之前創建的SKShapeNode。

首先,使其到之前紋理添加到視圖(在這種情況下,將來自另一節點清潔)

SKTexture *Mask = [self.view textureFromNode:edge]; 
[self addChild:edge]; //if you need physics borders 

其次,

SKCropNode *cropNode = [[SKCropNode alloc] init]; 
[cropNode setMaskNode:[SKSpriteNode spriteNodeWithTexture:Mask]]; 
[cropNode addChild: [SKSpriteNode spriteNodeWithTexture:rocksTiles size:CGSizeMake(w,h)]]; 
cropNode.position = CGPointMake(Mask.size.width/2,Mask.size.height/2); 
//note, anchorpoint of shape in 0,0, but rendered texture is in 0.5,0.5, so we need to dispose it 
[self addChild:cropNode]; 
+0

現在有些事情都是可能的。 (iOS 8.1): int deviceOSVersion = [[[[UIDevice currentDevice] systemVersion] floatValue]; if(deviceOSVersion> = 8.0) treeS.fillTexture = [SKTexture textureWithImage:[UIImage imageNamed:@「treeS」]]; – djdance

0

設置掩模節點的α位。0的伎倆:

circleMask.alpha = .0; 

編輯: 似乎只的Mac OS工作。

5

既然不能使用SKShapeNode作爲面膜我決定把它轉換爲SKSpriteNode

這是我的銀行代碼:

let shape : SKShapeNode = ... // create your SKShapeNode 
var view : SKView = ... // you can get this from GameViewController 

let texture = view.textureFromNode(shape) 
let sprite = SKSpriteNode(texture: texture) 
sprite.position = ... 

cropNode.mask = sprite 

而且它的工作:)

+0

看起來您需要將一個未使用的形狀節點添加到場景中。我建議你考慮從'CGPath'或'UIBezierPath'創建'UIImage'。然後您可以從圖像生成紋理。 – 0x141E

+0

嗨0x141E,其實我沒有添加***形狀***(SKShapeNode)到現場。將被保存的唯一節點是*** sprite ***。 –

+2

這是一個比接受的更好的解決方案 – 0x141E

1

有一個略顯尷尬的解決這個問題,我認爲這是比任何醞釀黑客略少討厭圍繞這個問題。只需將SKShapeNode包裝在SKNode中即可。我還沒有測試過這可能會導致什麼樣的性能,但是鑑於SKNode是非繪圖的,我希望它不會太重要。

let background = SKSpriteNode(imageNamed: "Background") 
let maskNode = SKShapeNode(path: MyPath) 
let wrapperNode = SKNode() 
let cropNode = SKCropNode() 

wrapperNode.addChild(maskNode) 
cropNode.maskNode = wrapperNode 
cropNode.addChild(background) 
相關問題