Как создать кольцо с 3D-эффектом, используя Sprite Kit?

Я хочу создать кольцо с 3D-эффектом, используя Sprite Kit. (СМОТРЕТЬ ФОТОГРАФИИ)

Я попытался создать подкласс SKNode и добавить два узла в качестве дочерних. (СМ. КОД)

Один узел был полным эллипсом SKShapeNode, а другой был полуэллипсом с использованием SKCropNode с более высоким zPosition.

Это выглядит хорошо, но SKCropNode увеличивает загрузку ЦП приложения с 40% до 99%.

Любые идеи о том, как снизить стоимость производительности SKCropNode, или какая-либо альтернатива, чтобы создать тот же эффект 3D кольца?

class RingNode: SKNode {

    let size: CGSize

    init(size: CGSize, color: SKColor)
    {
        self.size = size
        self.color = color

        super.init()

        ringPartsSetup()
    }

    private func ringPartsSetup() {

        // LEFT PART (half ellipse)
        let ellipseNodeLeft = getEllipseNode()
        let leftMask = SKSpriteNode(texture: nil, color: SKColor.blackColor(), size: CGSize(
            width: ellipseNodeLeft.frame.size.width/2,
            height: ellipseNodeLeft.frame.size.height))
        leftMask.anchorPoint = CGPoint(x: 0, y: 0.5)
        leftMask.position = CGPoint(x: -ellipseNodeLeft.frame.size.width/2, y: 0)
        let leftNode = SKCropNode()
        leftNode.addChild(ellipseNodeLeft)
        leftNode.maskNode = leftMask
        leftNode.zPosition = 10 // Higher zPosition for 3D effect
        leftNode.position = CGPoint(x: -leftNode.frame.size.width/4, y: 0)
        addChild(leftNode)

        // RIGHT PART (complete ellipse)
        let rightNode = getEllipseNode()
        rightNode.position = CGPoint(x: 0, y: 0)
        rightNode.zPosition = 5
        addChild(rightNode)
    }

    private func getEllipseNode() -> SKShapeNode {
        let ellipseNode = SKShapeNode(ellipseOfSize: CGSize(
            width: size.width,
            height: size.height))
        ellipseNode.strokeColor = SKColor.blackColor()
        ellipseNode.lineWidth = 5
        return ellipseNode
    }    
}

2 ответа

Решение

У вас есть правильная идея с вашим двухслойным подходом и полузакрытием сверху. Но вместо использования узла формы внутри узла обрезки, почему бы просто не использовать узел формы, путь которого является полуэллипсом? Создать один, используя либо CGPath или же UIBezierPath API - используйте круговую дугу с преобразованием, чтобы сделать его эллиптическим, - затем создайте свой SKShapeNode с этого пути.

Вы можете попробовать конвертировать ваши SKShapeNode для SKSpriteNode, Ты можешь использовать SKView textureFromNode: (но мы знаем о проблемах с масштабированием, которые требуют использования его только после добавления узла в представление и выполнения хотя бы одного цикла обновления) или с нуля с использованием изображения (созданного программно с CGBitmapContext, конечно).

Другие вопросы по тегам