Как я могу увеличивать радиус SKShapeNode на 1 пиксель каждую секунду?

#swift #sprite-kit #skshapenode

#swift #sprite-kit #skshapenode

Вопрос:

Я пытаюсь написать функцию, в которой я могу увеличивать радиус SKShapeNode каждую секунду, но не знаю как: (

     var eRadius: CGFloat = 20
    var eCircle = SKShapeNode()

    override func didMove(to view: SKView) {
            super.didMove(to: view)
    
            eCircle = SKShapeNode(circleOfRadius: eRadius)
            eCircle.strokeColor = .black
            eCircle.glowWidth = 1.0
            eCircle.fillColor = .white
            eCircle.fillTexture = SKTexture(imageNamed: "e")
            
            addChild(eCircle)

    gameTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(addRadius), userInfo: nil, repeats: true)
}
    
        @objc func addRadius(){
        eRadius  = 1
        ???? :(
        }
 

Спасибо!

Комментарии:

1. Вы можете изменить свойство path — и есть много способов получить круговой cg-путь, один из которых — UIBezierPath(ovalIn: …) с квадратом — это помогает?

2. Спасибо Shadowrun! Но я новичок в Swift и не знаю, как обрабатывать path после изменения…

Ответ №1:

Вот рабочее решение:

 import SpriteKit

class GameScene: SKScene {
    
    private var eRadius: CGFloat = 20
    private var eCircle = SKShapeNode()
    
    override func didMove(to view: SKView) {
        eCircle.strokeColor = .black
        eCircle.glowWidth = 1.0
        eCircle.fillColor = .white
        eCircle.fillTexture = SKTexture(imageNamed: "e")
        addChild(eCircle)
        
        run(SKAction.repeatForever(SKAction.sequence([SKAction.run {
            self.updateCirclePath()

            self.eRadius  = 1
        }, SKAction.wait(forDuration: 1.0)])))
    }
    
    private func updateCirclePath() {
        eCircle.path = UIBezierPath(ovalIn: CGRect(x: -eRadius * 0.5, y: -eRadius * 0.5, width: eRadius, height: eRadius)).cgPath
    }
}
 

По сути, вы создаете круг, используя UIBezierPath, а затем обновляете его по мере изменения вашего радиуса. Для обновления вы должны использовать вечно повторяющуюся последовательность действий, которая одновременно задает путь, а затем изменяет радиус. Я решил сначала выполнить путь, а затем обновить радиус для следующего предстоящего хода, для ясности.

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

В SpriteKit вы должны использовать SKActions для таймеров вместо очередей планирования или отправки. С SKActions все соответствует одному и тому же игровому времени, которое затем вы можете контролировать, делая паузу и что угодно.

Кроме того, существует несколько способов создания окружности с использованием UIBezierPath, включая овалы, скругленные прямоугольники и дуги: https://developer.apple.com/documentation/uikit/uibezierpath .