swift - SpriteKit: Cómo hacer agujeros en la capa con blendMode
sprite-kit mask (1)
Aquí hay un ejemplo de cómo crear una capa translúcida con un agujero perforado:
- (NOTA: el modo de mezcla de resumen no tiene en cuenta el alfa del sprite, por lo que debe usar un nodo de recorte)
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)
Tengo una escena simple con algunos elementos agregados a ella.
Ahora quiero centrarme en un elemento específico con una máscara, cortar un todo en la misma posición que el elemento en el que quiero centrarme. Muy similar a lo que podemos ver en algunos juegos cuando se inician por primera vez y muestran algún tipo de tutorial.
Básicamente estoy agregando una capa de pantalla completa con alpha=0.7
(para que el usuario aún pueda ver todo el contenido) pero luego agrego un círculo en una posición específica ya que esta capas son secundarias y establece blendMode=
. Resta por lo que "corta" un círculo de esta capa de pantalla completa, por lo que dentro de este círculo tienes una vista clara.
Tengo el siguiente código después de haber agregado todos los elementos en la pantalla.
// 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)
Pero esto simplemente agrega la capa de pantalla completa, sin agujeros circulares. Parece que está ignorando el nodo circle_mask. ¿Qué estoy haciendo mal?
Mi plan también es seguir moviendo la máscara del círculo para enfocarme en otros elementos en esta escena. Según entiendo. Restarlo debe restar solo de su nodo padre, que es la capa de pantalla completa con alpa=0.7
, ¿verdad?
Lo intenté con SKCropNode. Se agregó la capa de pantalla completa como elemento secundario en el nodo de recorte, luego se le asignó el círculo como máscara. Pero ahora está cortando casi todo pero solo mostrando un círculo de mi capa de pantalla completa, realmente necesito el resultado invertido de este nodo de recorte.
El problema con blendMode es que se ejecuta en el framebuffer final, pero lo que necesito es ejecutarlo solo en el nodo primario, por lo que no corta todo detrás del nodo cuando se usa .Stract