是否可以在Sprite Kit中使用圆圈(SKShapeNode)作为遮罩?

Mas*_*uin 10 iphone objective-c ios7 sprite-kit skcropnode

我正在尝试在Sprite Kit项目中创建一个圆形蒙版.我像这样创建圆圈(将其定位在屏幕的中心):

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];
circleMask.name=@"circleMask";
Run Code Online (Sandbox Code Playgroud)

在代码中,我将其设置为以下掩码cropNode:

[cropNode setMaskNode:circleMask];
Run Code Online (Sandbox Code Playgroud)

... ...而不是显示在圆圈内的内容,掩码显示为正方形.

是否可以使用a SKShapeNode作为蒙版,还是需要使用图像?

Mas*_*uin 12

经过多次咒骂,搜索网页,以及在Xcode中进行实验,我有一个非常hacky修复.

请记住,这是一个非常讨厌的黑客 - 但你可以责怪Sprite Kit的实现SKShapeNode.将填充添加到路径会导致以下情况:

  • 为场景添加一个额外的节点
  • 路径变得不可屏蔽 - 它出现在掩模上方
  • 使任何非SKSpriteNode兄弟节点不可屏蔽(例如SKLabelNodes)

不是理想的事态.

Tony Chamblee的进度计时器的启发下,'修复'是完全免除填充,只需使用路径的笔划:

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];
circleMask.name=@"circleMask";

[cropNode setMaskNode:circleMask];
Run Code Online (Sandbox Code Playgroud)

如评论所示,您需要将半径设置为通常的半径,并将线宽设置为半径的两倍.

希望Apple将来会看到这个; 现在,这个hack是我发现的最好的解决方案(除了使用图像,如果你的面具需要是动态的,它不会真正起作用).


djd*_*nce 5

是的,在当前的Sprite-Kit实现中不可能使用填充色的shapenode.我想这是一个错误.

但!

您始终可以将形状渲染为纹理并将其用作蒙版!

例如,let edge是之前创建的SKShapeNode.

首先,添加到视图之前将其渲染为纹理(在这种情况下,它将从另一个节点清除)

SKTexture *Mask = [self.view textureFromNode:edge];
[self addChild:edge]; //if you need physics borders
Run Code Online (Sandbox Code Playgroud)

第二,

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];
Run Code Online (Sandbox Code Playgroud)


Luc*_*tti 5

由于我不能使用SKShapeNode作为掩码,我决定将其转换为SKSpriteNode.

这是我的Swift代码:

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
Run Code Online (Sandbox Code Playgroud)

它确实有效:)

  • 这是一个比被接受的解决方案更好的解决方案 (3认同)