13

Помимо того, что вопрос, заданный здесь: Draw a hole in a rectangle with SpriteKit?, не получил удовлетворительного ответа, самое важное различие между ними состоит в том, что этот вопрос требует отсутствия обходных решений и, в частности, просит об изменении функциональности SKCropNodes.Как вырезать случайные дыры в SKSpriteNodes

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

Поэтому швейцарский сыр пример:

Представьте себе кучу случайно размеров прямоугольных SKSpriteNodes, заполненный различными оттенками сырного как цвет.

Как сделать швейцарский сыр из каждого путем резки случайных кругов из каждого кусочка сыра?

Если SKCropNodes являются кругами, они оставляют круговые куски сыра, а не разрезают отверстия из кусков сыра. Есть ли способ инвертировать поведение SKCropNodes, чтобы вместо этого вырезать отверстия?

+0

Возможный дубликат [Нарисуйте отверстие в прямоугольнике с помощью SpriteKit?] (Http://stackoverflow.com/questions/34576112/draw-a-hole-in-a-rectangle-with-spritekit) – Knight0fDragon

ответ

7

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

..cutting случайных кругов из каждого кусочка сыр?

В этом проекте я попытался перестроить типичный прямоугольник (кусок сыра) со случайными отверстиями, затем я извлечу эти отверстия и собрал их в массив.

import SpriteKit 
class GameScene: SKScene { 
    struct Cheese 
    { 
     static let color1 = SKColor(red: 255/255, green: 241/255, blue: 173/255, alpha: 1) 
     static let color2 = SKColor(red: 255/255, green: 212/255, blue: 0/255, alpha: 1) 
     static let color3 = SKColor(red: 204/255, green: 170/255, blue: 0/255, alpha: 1) 
     static let color4 = SKColor(red: 140/255, green: 116/255, blue: 0/255, alpha: 1) 
    } 
    let cheeseColor = [Cheese.color1,Cheese.color2,Cheese.color3,Cheese.color4] 
    override func didMove(to view: SKView) {   
     let totHoles = randomNumber(range:4...8) 
     let color = randomNumber(range:0...3) 
     let cheeseCropNode = makeCheese(size: CGSize(width:400,height:200),color: cheeseColor[color], totHoles:totHoles) 
     cheeseCropNode.position = CGPoint(x:0,y:-50) 
     addChild(cheeseCropNode) 
     // Start to collect and show holes 
     var holes = [SKNode]() 
     var counter = 1 
     let _ = cheeseCropNode.enumerateChildNodes(withName: "//hole*", using:{ node, stop in 
      // node is the hole 
      let pos = self.convert(node.position, from: cheeseCropNode) 
      let sprite = SKSpriteNode.init(color: .red, size: node.frame.size) 
      sprite.position = pos 

      //Remove these shapes, it's just to debug 
      let shape = SKShapeNode.init(rect: sprite.frame) 
      shape.strokeColor = .red 
      self.addChild(shape) 
      // -- end to remove 

      let holeTxt = SKView().texture(from: cheeseCropNode, crop: sprite.frame) 
      let hole = SKSpriteNode.init(texture: holeTxt) 
      hole.position = CGPoint(x:-(self.frame.maxX)+(100*CGFloat(counter)),y:150) 
      hole.name = node.name 
      self.addChild(hole) 
      holes.append(hole) 
      counter += 1 
     }) 
    } 

    func randomNumber(range: ClosedRange<Int> = 1...6) -> Int { 
     let min = range.lowerBound 
     let max = range.upperBound 
     return Int(arc4random_uniform(UInt32(1 + max - min))) + min 
    } 
    func randomCGFloat(min: CGFloat, max: CGFloat) -> CGFloat { 
     return (CGFloat(arc4random())/CGFloat(UINT32_MAX)) * (max - min) + min 
    } 
    func makeCheese(size:CGSize , color:SKColor, totHoles:Int)->SKCropNode { 
     let cropNode = SKCropNode() 
     let cheese = SKSpriteNode.init(color: color, size: size) 
     for i in 0..<totHoles { 
      let radius = randomCGFloat(min:20.0, max:50.0) 
      let circle = SKShapeNode(circleOfRadius: radius) 
      circle.position = CGPoint(x:randomCGFloat(min:-size.width/2, max:size.width/2),y:randomCGFloat(min:-size.height/2, max:size.height/2)) 
      circle.fillColor = color 
      circle.blendMode = .subtract 
      circle.name = "hole\(i)" 
      cheese.addChild(circle) 
     } 
     cropNode.addChild(cheese) 
     cropNode.maskNode = cheese 
     return cropNode 
    } 
} 

Результат:

P.S. Не обращайте внимание на красные прямоугольники, это просто, чтобы показать вам отверстие:

enter image description here

Если вы хотите точно обращенную отверстия (отрицательное изображение), вы можете использовать SKCropNode с hole.blendMode, например:

Заменитель эту часть кода:

// -- end to remove 

       let holeTxt = SKView().texture(from: cheeseCropNode, crop: sprite.frame) 
       let hole = SKSpriteNode.init(texture: holeTxt) 
       hole.position = CGPoint(x:-(self.frame.maxX)+(100*CGFloat(counter)),y:150) 
       hole.name = node.name 
       self.addChild(hole) 
       holes.append(hole) 
       counter += 1 

с этой частью:

// -- end to remove 

      let holeTxt = SKView().texture(from: cheeseCropNode, crop: sprite.frame) 
      let hole = SKSpriteNode.init(texture: holeTxt) 
      hole.position = CGPoint(x:-(self.frame.maxX)+(100*CGFloat(counter)),y:150) 
      hole.name = node.name 

      let negativeCropHole = SKCropNode() 
      let shadow = SKShapeNode.init(rect: hole.frame) 
      shadow.fillColor = (node as! SKShapeNode).fillColor 
      shadow.strokeColor = SKColor.clear 
      hole.blendMode = .subtract 
      negativeCropHole.addChild(shadow) 
      negativeCropHole.maskNode = shadow 
      negativeCropHole.addChild(hole) 
      negativeCropHole.name = hole.name 
      self.addChild(negativeCropHole) 
      holes.append(negativeCropHole) 
      counter += 1 

Результат (другой пример):

enter image description here

Надежда это пример и этот код поможет вам получить ваши цели, я использовал прямоугольники, чтобы сделать маски, но ваш может создать CGPaths если тебе нужно.

Смежные вопросы