SpriteKit:如何使用混合模式在图层中打洞

SpriteKit: Howto make holes in layer with blendMode

我有一个添加了一些元素的简单场景。

现在我想专注于一个带有遮罩的特定元素,并在与我想要专注的元素相同的位置切割一个整体。非常类似于我们在某些游戏上看到的,当它们第一次启动时显示某种教程。

基本上我添加了一个带 alpha=0.7 的全屏层(这样用户仍然可以看到所有内容),然后在特定位置添加一个圆圈作为该层的子层并设置 blendMode=。从这个全屏图层中减去 "cuts" 一个圆圈,在这个圆圈内你有一个清晰的视图。

将所有元素添加到屏幕后,我得到以下代码。

// before this code i added some basic elements like circles and backgrounds
let mask = SKSpriteNode(color: .blackColor(), size: self._screenSize)
mask.anchorPoint = CGPoint.zero
mask.position = CGPoint.zero
mask.zPosition = 100
mask.alpha = 0.7

let circle = SKShapeNode(circleOfRadius: Constants.Config.playersize*2)
circle.fillColor = .blackColor()
circle.lineWidth = 0
let circle_mask = SKSpriteNode(texture: SKView().textureFromNode(circle, crop: circle.frame))
circle_mask.blendMode = .Subtract
circle_mask.zPosition = 101

// now show the layer with alpha=0.7 and the circle mask being at the same position as my player element i want to focus on
mask.addChild(circle_mask)
circle_mask.position = player.position
self.addChild(mask)

但是这个只是加了全屏层,没有圆孔。看起来它忽略了 circle_mask 节点。我做错了什么?

我的计划也是不断移动圆形遮罩,以专注于此场景中的其他元素。我认为。减去它应该只从它的父节点减去,它是带有 alpa=0.7 的全屏层,对吗?

我刚刚尝试使用 SKCropNode。将全屏层作为子层添加到裁剪节点中,然后将圆指定为蒙版。但是现在它几乎切掉了所有东西,只显示了我的全屏图层的一个圆圈,我实际上需要这个裁剪节点的反转结果。

blendMode 的问题是 运行 它在最终的帧缓冲区上,但我需要的是 运行 它只在父节点上,所以它不会剪切后面的所有内容使用 .Subtract

时的节点

下面是一个关于如何创建带有打孔的半透明层的示例:

-(注意:.subtract 混合模式不考虑 sprite 的 alpha,因此您需要使用裁剪节点)

self.backgroundColor = .red


//Our transparent overlay
let fullScreen = SKSpriteNode(color: .black, size: self.size)
fullScreen.position = CGPoint.zero
fullScreen.zPosition = 100
fullScreen.alpha = 0.7

//let's make a mask to punch circles in our shape
let mask = SKSpriteNode(color: .white, size: self.size)
mask.position = CGPoint.zero
mask.zPosition = 100
mask.alpha = 1

let circle = SKShapeNode(circleOfRadius: 20*2)
circle.fillColor = .white
circle.lineWidth = 0
circle.alpha = 1

//let circle_mask = SKSpriteNode()
circle.blendMode = .subtract
mask.addChild(circle)

//let's create the node to place on screen
let crop = SKCropNode()
crop.maskNode = mask
crop.addChild(fullScreen)

self.addChild(crop)