带SKShapeNode

时间:2017-03-02 18:45:55

标签: swift sprite-kit

我有以下代码,用于对场景构建器中现有的矩形进行舍入...

btOk.path = UIBezierPath(roundedRect: CGRect(x: -62.5,y:-25,width: 125, height: 50), cornerRadius: 10).cgPath

但是,如果我尝试使用相同的init来围绕另一个更大的矩形的角落,它甚至不会接近工作。它只是使宽度HUUUUGE(想象特朗普)。

scene.enumerateChildNodes(withName: "//*"){
            node,stop in

    if let name = node.name{
        if name.contains("round"){
            if let shapeNode = node as? SKShapeNode{
                print(shapeNode.frame.width) //500
                shapeNode.path = UIBezierPath(roundedRect: CGRect(x: -250,y:-100,width: 500, height: 200), cornerRadius: 50).cgPath
                print(shapeNode.frame.width) //5735
             }
        }
    }
}

btOk也是SKShapeNode。这两者之间我错过了什么?有一点需要注意的是,我正在通过这样的场景的孩子进行枚举,因为这个场景位于SKReferenceNode中。也许这与它有关?

修改

从@Ron Myschuk接受指示,我已经解决了这个问题,因为它是这样的PITA,我也创建了一个扩展。所以现在我可以在需要时非常轻松地绕过任何SKShapeNode的角落。即使它是在场景编辑器中创建的。注意,只有在shape节点没有子节点时才应该使用它。否则这些孩子也将被移除。

extension SKShapeNode {
    func roundCorners(topLeft:Bool,topRight:Bool,bottomLeft:Bool,bottomRight:Bool,radius: CGFloat,parent: SKNode){
        let newNode = SKShapeNode(rect: self.frame)
        newNode.fillColor = self.fillColor
        newNode.lineWidth = self.lineWidth
        newNode.position = self.position
        newNode.name = self.name
        self.removeFromParent()
        parent.addChild(newNode)
        var corners = UIRectCorner()
        if topLeft { corners = corners.union(.bottomLeft) }
        if topRight { corners = corners.union(.bottomRight) }
        if bottomLeft { corners = corners.union(.topLeft) }
        if bottomRight { corners = corners.union(.topRight) }
        newNode.path = UIBezierPath(roundedRect: CGRect(x: -(newNode.frame.width / 2),y:-(newNode.frame.height / 2),width: newNode.frame.width, height: newNode.frame.height),byRoundingCorners: corners, cornerRadii: CGSize(width:radius,height:radius)).cgPath
    }
}

并像这样使用它......

aShapeNode.roundCorners(topLeft: true, topRight: true, bottomLeft: false, bottomRight: false, radius: 5,parent: popup)

1 个答案:

答案 0 :(得分:3)

不是您想要听到的内容,而是因为您无法在场景编辑器中设置SKShapeNode的宽度(据我所知)。为了使ShapeNode的宽度为500,您必须调整xScale。然后,当您调整它时,xScale会将其自身重新应用于路径(呈指数级增长)。如果您在代码中创建SKShapeNode,则调整圆角没有问题

    let round = SKShapeNode(rect: CGRect(x: 0, y: -150, width: 500, height: 200))
    round.fillColor = .red
    addChild(round)
    print(round.frame.width)
    round.path = UIBezierPath(roundedRect: CGRect(x: -250, y: -100, width: 500, height: 200), cornerRadius: 50).cgPath
    print(round.frame.width)
  

修改

如果你已经开始使用场景编辑器,你可以放置你的ShapeNode并将其拉伸到你想要的位置,然后你可以在代码中做一个小的转换来获得你想要的结果

    if let round = self.childNode(withName: "biground") as? SKShapeNode {

        let biground = SKShapeNode(rect: round.frame)
        biground.fillColor = round.fillColor
        biground.position = round.position
        addChild(biground)
        round.removeFromParent()

        print(biground.frame.width)
        biground.path = UIBezierPath(roundedRect: CGRect(x: -250, y: -100, width: 500, height: 200), cornerRadius: 50).cgPath
        print(biground.frame.width)
    }

这只是根据您在场景编辑器中概述的内容在代码中重新创建形状并完美地围绕边缘

  

编辑2

我一直认为SKShapeNodes效率很低(我很确定他们也会泄露内存)。所以我总是设置我的圆形矩形。

    let outsideTexture = SKTexture(imageNamed: "round_square_white")
    let outside = SKSpriteNode(texture: outsideTexture)      
    let insetX: CGFloat = 20
    let insetY: CGFloat = 20
    let cellSize = CGSize(width: 500.0, height: 500.0)

    outside.centerRect = CGRect(x: CGFloat(insetX / outside.size.width), y: CGFloat(insetY / outside.size.height), width: CGFloat((outside.size.width - insetX * 2) / outside.size.width), height: CGFloat((outside.size.height - insetY * 2) / outside.size.height))
    //outside.position = CGPointMake(gameModel.gameWidth / 2, (outside.size.height) / 2);
    outside.xScale = cellSize.width / outside.size.width
    outside.yScale = cellSize.height / outside.size.height
    outside.zPosition = 10
    outside.position = CGPoint(x: CGFloat(0), y: CGFloat(-0.35 * self.size.height / 2))
    self.addChild(outside)

值得注意的是,这完全呈现了圆角方形/矩形,但是与场景编辑器中的比例问题类似,您必须在此处放置一个空单元格以添加子项,否则它们会缩放到圆角正方形。