2013-11-26 14 views
10

私はスプライトキットプロジェクトで円形マスクを作成しようとしています。私はこの(画面の中央にそれを配置する)ように円を作成します。スプライトキットで円(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で実験した後、私は本当にハックリな修正をしました。

これは本当に不快なハックですが、スプライトキットの実装SKShapeNodeに責任を負うことができます。パスに塗りつぶしを追加すると、次が発生します。

  • パスがマスク不可となり
  • あなたのシーンに追加のノードを追加する - それが表示されますマスク
  • 「上」(任意の非SKSpriteNode兄弟がマスク不可ノードになり例:SKLabelNodes)

理想的な状態ではありません。コメントしたよう

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]; 

が、あなたは何の半分までの半径を設定する必要があります。Tony Chamblee's progress timerに触発

は、「修正」は完全に塗りつぶしを不要にし、ちょうどパスのストロークを使用することです'dは通常持っていて、線幅は半径を2倍にします。

Appleがこれを将来見ていくことを願っています。今のところ、このハックは私が見つけた最良の解決策です(イメージを使用する以外、マスクが動的でなければならない場合は実際には機能しません)。

5

はい、現在のスプライトキットの実現では、塗りつぶしのシェイプノードを使用することはできません。それはバグだと思います。

しかし!

いつでもシェイプをテクスチャにレンダリングしてマスクとして使用できます。

たとえば、のエッジは以前に作成されたSKShapeNodeです。

まず、(この場合には、それが別のノードからきれいにする)ビューに追加前テクスチャ

にマスクノードのアルファ設定
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

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

第それをレンダリングします。0トリックん:

circleMask.alpha = .0; 

EDIT: は、Mac OSのために働くようです。

5

私はSKSpriteNodeに変換することを決定したマスクとしてSKShapeNodeを使用することはできませんので。ここで

は、それが私のスウィフトコードです:

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 

そして、それはありません仕事:)私は少し小さい厄介mootedハックのいずれよりもあると信じて、この問題に少しぎこちない解決策はあり

+0

未使用のシェイプノードをシーンに追加する必要があるようです。 'CGPath'や' UIBezierPath'から 'UIImage'を作成することをお勧めします。その後、イメージからテクスチャを生成することができます。 – 0x141E

+0

こんにちは0x141E、実際には***シェイプ***(SKShapeNode)をシーンに追加していません。保存される唯一のノードは***スプライト***です。 –

+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) 
関連する問題