SKSpriteNode - 创建一个圆角节点?

时间:2014-02-11 07:04:58

标签: ios iphone objective-c sprite-kit

有没有办法让SKSpriteNode圆形走投无路?我正在尝试用颜色填充的SKSpriteNode创建一个Tile likesqaure块:

SKSpriteNode *tile = [SKSpriteNode spriteNodeWithColor:[UIColor colorWithRed:0.0/255.0
                                                                           green:128.0/255.0
                                                                            blue:255.0/255.0
                                                                           alpha:1.0] size:CGSizeMake(30, 30)];

我怎样才能绕过角落?

谢谢!

8 个答案:

答案 0 :(得分:47)

要获得圆角节点,您可以使用2种方法,每种方法都需要使用SKShapeNode。

第一种方法是使用SKShapeNode并将其路径设置为圆角矩形,如下所示:

SKShapeNode* tile = [SKShapeNode node];
[tile setPath:CGPathCreateWithRoundedRect(CGRectMake(-15, -15, 30, 30), 4, 4, nil)];
tile.strokeColor = tile.fillColor = [UIColor colorWithRed:0.0/255.0
                                                    green:128.0/255.0
                                                     blue:255.0/255.0
                                                    alpha:1.0];

另一个使用sprite节点,crop节点和带圆角矩形的SKShapeNode作为裁剪节点掩码:

SKSpriteNode *tile = [SKSpriteNode spriteNodeWithColor:[UIColor   colorWithRed:0.0/255.0
                                                                           green:128.0/255.0
                                                                            blue:255.0/255.0
                                                                           alpha:1.0] size:CGSizeMake(30, 30)];
SKCropNode* cropNode = [SKCropNode node];
SKShapeNode* mask = [SKShapeNode node];
[mask setPath:CGPathCreateWithRoundedRect(CGRectMake(-15, -15, 30, 30), 4, 4, nil)];
[mask setFillColor:[SKColor whiteColor]];
[cropNode setMaskNode:mask];
[cropNode addChild:tile];

如果你的瓷砖是一种纯色,我建议你选择第一种方法。

答案 1 :(得分:13)

在Swift 3中,您可以创建:

let tile = SKShapeNode(rect: CGRect(x: 0, y: 0, width: 30, height: 30), cornerRadius: 10)

答案 2 :(得分:6)

希望这会有所帮助:

SKSpriteNode *make_rounded_rectangle(UIColor *color, CGSize size, float radius)
{
    UIGraphicsBeginImageContext(size);
    [color setFill];
    CGRect rect = CGRectMake(0, 0, size.width, size.height);
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius];
    [path fill];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    SKTexture *texture = [SKTexture textureWithImage:image];
    return [SKSpriteNode spriteNodeWithTexture:texture];
}

答案 3 :(得分:4)

真的很简单.......

class YourSprite: SKSpriteNode {

    func yourSetupFunction() {

          texture = SKTexture( image: UIImage(named: "cat")!.circleMasked! )

除此之外别无其他。

你真的无法使用 SKShapeNode。

就是这么简单。使用SKShapeNode是一个疯狂的性能影响,它不是正确的解决方案,它毫无意义,SKShapeNode的目的与此问题无关。

enter image description here

看看他们所有小猫!

circleMasked的代码很简单:

(所有处理图片的项目无论如何都需要这个。)

extension UIImage {

    var isPortrait:  Bool    { return size.height > size.width }
    var isLandscape: Bool    { return size.width > size.height }
    var breadth:     CGFloat { return min(size.width, size.height) }
    var breadthSize: CGSize  { return CGSize(width: breadth, height: breadth) }
    var breadthRect: CGRect  { return CGRect(origin: .zero, size: breadthSize) }

    var circleMasked: UIImage? {

        UIGraphicsBeginImageContextWithOptions(breadthSize, false, scale)
        defer { UIGraphicsEndImageContext() }

        guard let cgImage = cgImage?.cropping(to: CGRect(origin:
            CGPoint(
                x: isLandscape ? floor((size.width - size.height) / 2) : 0,
                y: isPortrait  ? floor((size.height - size.width) / 2) : 0),
            size: breadthSize))
        else { return nil }

        UIBezierPath(ovalIn: breadthRect).addClip()
        UIImage(cgImage: cgImage, scale: 1, orientation: imageOrientation)
            .draw(in: breadthRect)
        return UIGraphicsGetImageFromCurrentImageContext()
    }

// classic 'circleMasked' stackoverflow fragment
// courtesy Leo Dabius /a/29047372/294884
}

这就是它的全部内容。

答案 4 :(得分:3)

这很大程度上受到了已接受的答案的启发,但它使用了一种更易读的方式来创建SKShapeNode并修复了裁剪周围恼人的像素线。看起来像一个小细节,但它可能花费几分钟。

CGFloat cornerRadius = 15;
SKCropNode *cropNode = [SKCropNode node];
SKShapeNode *maskNode = [SKShapeNode shapeNodeWithRectOfSize:scoreNode.size cornerRadius:cornerRadius];
[maskNode setLineWidth:0.0];
[maskNode setFillColor:[UIColor whiteColor]];
[cropNode setMaskNode:maskNode];
[cropNode addChild:scoreNode];

答案 5 :(得分:2)

斯威夫特4:

在您将精灵添加到其父级之前,可以创建一个很好的解决方案,我已经为您提供了一个可以根据需要进行更正的扩展:

extension SKSpriteNode {
    func addTo(parent:SKNode?, withRadius:CGFloat) {
        guard parent != nil else { return }
        guard  withRadius>0.0 else {
            parent!.addChild(self)
            return
        }
        let radiusShape = SKShapeNode.init(rect: CGRect.init(origin: CGPoint.zero, size: size), cornerRadius: withRadius)
        radiusShape.position = CGPoint.zero
        radiusShape.lineWidth = 2.0
        radiusShape.fillColor = UIColor.red
        radiusShape.strokeColor = UIColor.red
        radiusShape.zPosition = 2
        radiusShape.position = CGPoint.zero
        let cropNode = SKCropNode()
        cropNode.position = self.position
        cropNode.zPosition = 3
        cropNode.addChild(self)
        cropNode.maskNode = radiusShape
        parent!.addChild(cropNode)
    }
}

用法:

let rootNode = SKSpriteNode(color: .white, size: self.size)
rootNode.alpha = 1.0
rootNode.anchorPoint = CGPoint.zero
rootNode.position = CGPoint.zero
rootNode.zPosition = 1
rootNode.name = "rootNode"
rootNode.addTo(parent: self, withRadius: 40.0)

答案 6 :(得分:1)

来自班级参考:

“SKSpriteNode是绘制纹理图像,彩色方块或与颜色混合的纹理图像的节点。”

似乎最简单的方法是绘制一个带圆角的块,然后使用以下类方法之一:

  • spriteNodeWithImageNamed:
  • spriteNodeWithTexture:
  • spriteNodeWithTexture:尺寸:

答案 7 :(得分:0)

这是一个基于接受答案的第二个解决方案的Swift 3片段。

func createPlayerRoundedNode(){
    let tile = SKSpriteNode(color: .white, size: CGSize(width: 30, height: 30))
    tile.zPosition = 3
    tile.name = "tile node"
    let cropNode = SKCropNode()
    cropNode.zPosition = 2
    cropNode.name = "crop node"
    let mask = SKShapeNode(rect: CGRect(x: 0, y: 0, width: 30, height: 30), cornerRadius: 10)
    mask.fillColor = SKColor.darkGray
    mask.zPosition = 2
    mask.name = "mask node"
    cropNode.maskNode = mask
    self.addChild(cropNode)
    cropNode.addChild(tile)
}