SpriteKit: Как сделать отверстия в слое с помощью blendMode

У меня есть простая сцена с некоторыми элементами, добавленными к ней.

Теперь я хочу сфокусироваться на конкретном элементе с маской, вырезать целое в той же позиции, что и элемент, на котором я хочу сфокусироваться. Очень похоже на то, что мы видим в некоторых играх, когда они запускаются впервые, показывая какое-то руководство.

В основном я добавляю полноэкранный слой с alpha=0.7 (так что пользователь по-прежнему видит все содержимое), но затем добавьте круг в определенной позиции, так как этот слой дочерний и установить blendMode=, Вычтите, чтобы он "обрезал" круг из этого полноэкранного слоя, чтобы внутри этого круга вы имели четкое представление.

У меня есть следующий код после того, как я добавил все элементы на экран.

// 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 он не обрезал все за узлом.

1 ответ

Решение

Вот пример того, как создать полупрозрачный слой с пробитым отверстием в нем:

- (ПРИМЕЧАНИЕ. Режим смешивания.subtract не учитывает альфа-спрайт, поэтому необходимо использовать узел обрезки)

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)
Другие вопросы по тегам