2016-11-20 2 views
2

Ich habe eine einfache Szene mit einigen Elementen hinzugefügt.SpriteKit: Wie mache ich Löcher in der Ebene mit blendMode

Jetzt möchte ich konzentrieren auf ein bestimmtes Element mit einer Maske ein Schnitt ein Ganzes an der gleichen Position wie das Element, das ich konzentrieren möchte. Sehr ähnlich zu dem, was wir in einigen Spielen sehen können, wenn sie zum ersten Mal mit einer Art Tutorial beginnen.

Grundsätzlich füge ich einen Vollbild-Layer mit alpha=0.7 hinzu (damit der Benutzer immer noch den gesamten Inhalt sieht), aber füge dann einen Kreis an einer bestimmten Position als dieses Layer-Kind ein und setze blendMode=. Subtrahieren Sie so, dass ein Kreis von dieser Vollbild-Ebene "ausgeschnitten" wird, so dass Sie innerhalb dieses Kreises eine klare Sicht haben.

Ich habe den folgenden Code, nachdem ich alle Elemente auf dem Bildschirm hinzugefügt haben.

// 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) 

Aber das fügt einfach die Vollbildschicht, keine Kreislöcher hinzu. Sieht so aus, als würde der Knoten circle_mask ignoriert. Was mache ich falsch?

Mein Plan ist auch, die Kreismaske weiter zu bewegen, um sich auf andere Elemente in dieser Szene zu konzentrieren. Wie ich es verstehe. Subtrahieren Sie es subtrahieren nur von seinem Elternknoten, der die Vollbild-Ebene mit alpa=0.7 ist, richtig?

Ich habe gerade mit SKCropNode versucht. Der Vollbild-Layer wurde als untergeordnetes Element in den Schnittknoten eingefügt und dann der Kreis als Maske zugewiesen. Aber jetzt, wo es fast alles ausschneidet, aber nur einen Kreis meiner Fullscreen-Ebene zeigt, brauche ich eigentlich das invertierte Ergebnis dieses Crop-Knotens.

Das Problem mit blendmode, dass ist es läuft auf dem letzten Framebuffer, aber was ich brauche, ist es auf dem übergeordneten Knoten nur zu laufen, so dass es nicht alles hinter dem Knoten schneiden, wenn .Subtract mit

+0

Sie fügen nie Kreis zur Kreismaske hinzu, Sie machen es einfach als eine Textur, die zu nichts passt. Machen Sie Kreismaske die volle Black Box. Und füge Kreis als Kind hinzu. Alpha-Blending tritt ein und erzeugt das Loch. Maskierung funktioniert auch nicht auf einem Alpha-Level, es ist einfach an und aus, so müssen Sie eine transparente Textur als Ihre normale Textur hinzufügen, dann haben Sie Ihre Kreismaske, um das Loch zu schlagen – Knight0fDragon

+0

@ Knight0fDragon: Ich verstehe es nicht . Ist mein Code nicht genau das, was Sie beschrieben haben? Meine Vollbild-Ebene hat bereits Alpha = 0.7. Jetzt füge ich das Kreis-Sprite als Kind hinzu. Aber wie mache ich das "Alpha Blending", über das du schreibst? Offensichtlich ist blendMode = .Subtract falsch. Am Ende füge ich meine Maske mit dem Kreiskind in die Szene ein. Können Sie einen korrigierten Code bereitstellen? – NovumCoder

+0

nein ist es nicht, jetzt, wo ich auf einem PC bin, werde ich versuchen und eine Antwort für Sie schreiben – Knight0fDragon

Antwort

2

Hier ist ein Beispiel dafür, wie eine lichtdurchlässige Schicht mit einem Loch in sie gestanzt erstellen:

- (Hinweis: .subtract Mischmodus findet nicht alpha des Sprites in Betracht zieht, so müssen Sie einen Ernteknoten verwenden)

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) 
+0

Vielen Dank. Funktioniert super. Aber kannst du erklären, warum der Kreis SKShapeNode sein muss? Ich habe es mithilfe von SKSpriteNode in SKTexture mit textureFromNode konvertiert, sodass es nicht mehr funktioniert. – NovumCoder

+0

Sie sind nicht richtig mischen, können Sie nur Knoten auf Knoten mischen – Knight0fDragon

+0

Grundsätzlich ist das Alpha nicht 0 im schwarzen Bereich, es ist 1. Wenn Sie Ihre Textur mit einem Alpha Null, sollte es funktionieren – Knight0fDragon

Verwandte Themen