Подтвердить что ты не робот

SKSpriteNode - создать круглый угол node?

Есть ли способ сделать SKSpriteNode круглым? Я пытаюсь создать Tile likesqaure блоки с заполненным цветом SKSpriteNode:

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)];

Как я могу сделать это заодно?

Спасибо!

4b9b3361

Ответ 1

Чтобы получить закругленный угол node, вы можете использовать 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];

Другой использует спрайт node, обрез node и 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];

Если ваши плитки имеют один сплошной цвет, я предлагаю вам перейти к первому подходу.

Ответ 2

В Swift 3 вы можете создать с помощью:

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

Ответ 3

Надеюсь, что это поможет:

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];
}

Ответ 4

Это сильно вдохновлено принятым ответом, но он использует более читаемый способ создания 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

Это действительно так просто.......

class YourSprite: SKSpriteNode {

    func yourSetupFunction() {

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

Нет ничего более.

Вы действительно не можете использовать SKShapeNode.

Это просто так просто. Это безумная производительность, использующая SKShapeNode, это не правильное решение, это бессмысленно сложно, и цель SKShapeNode просто не имеет никакого отношения к этой проблеме.

введите описание изображения здесь

Посмотрите на все их котята!

Код для 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
}

Это все, что нужно.

Ответ 6

из ссылки на класс:

"SKSpriteNode - это node, который рисует текстурированное изображение, цветной квадрат или текстурированное изображение, смешанное с цветом".

Кажется, самый простой способ - нарисовать блок с закругленными углами, а затем использовать один из этих методов класса:

  • spriteNodeWithImageNamed:
  • spriteNodeWithTexture:
  • spriteNodeWithTexture: Размер:

Ответ 7

Вот фрагмент 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)
}