Создать бесконечный cgpath без рамок

Мне нужно постоянно создавать cgpath. На данный момент я делаю это так:

 func createLine(){
        var rand = randomBetweenNumbers(1, 2)
        currentY--
        if rand < 1.5{
            currentX--
            CGPathAddLineToPoint(leftPath, nil, currentX, currentY)
        }else{
            currentX++
            CGPathAddLineToPoint(leftPath, nil, currentX, currentY)
        }
        CGPathAddLineToPoint(rightPath, nil, currentX+tileSize, currentY)
        lineNode.path = leftPath
        rightNode.path = rightPath

}

И назовите это так:

NSTimer.scheduledTimerWithTimeInterval(0.05, target: self, selector: Selector("startTile"), userInfo: nil, repeats: true)

Но проблема в том, что со временем кадры падают все ниже и ниже. Есть ли что-то, что я должен изменить, чтобы частота кадров больше не падала?

Моя цель - создать случайный бесконечный путь.

1 ответ

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

Самым простым из них является периодическое преобразование ранее нарисованных линий в SKTexture и отображать результаты в виде текстуры SKSpriteNode, Вот шаги:

  1. Создать SKNode для использования в качестве линейного контейнера
  2. Создать SKSpriteNode это будет использоваться как холст линии
  3. Создать SKShapeNode использоваться для рисования новых линий
  4. Добавьте контейнер на сцену и узел Canvas и shape в контейнер
  5. Нарисуйте набор связанных отрезков линии, используя path свойство узла формы
  6. Когда счетчик строк достигает заданного значения, преобразуйте содержимое контейнера в 'SKTexture'
  7. Установите свойство текстуры холста на SKTexture, Обратите внимание, что поскольку canvas также является дочерним элементом контейнера, его содержимое также будет добавлено в текстуру.
  8. Вспенить, промыть, повторить шаги 5 - 7

Вот пример реализации в Swift, которая рисует бесконечный набор линий со скоростью 60 FPS на устройстве iPhone 6 (вы должны тестировать производительность на устройстве, а не на симуляторе):

class GameScene: SKScene {
    // 1. Create container to hold new and old lines
    var lineContainer = SKNode()
    // 2. Create canvas
    var lineCanvas:SKSpriteNode?
    // 3. Create shape to draw new lines
    var lineNode = SKShapeNode()

    var lastDrawTime:Int64 = 0
    var lineCount = 0
    var timeScan:Int64 = 0
    var path = CGPathCreateMutable()

    var lastPoint = CGPointZero

    override func didMoveToView(view:SKView) {
        scaleMode = .ResizeFill

        // 4. Add the container to the scene and the canvas to the container 
        addChild(lineContainer)
        lineCanvas = SKSpriteNode(color:SKColor.clearColor(),size:view.frame.size)
        lineCanvas!.anchorPoint = CGPointZero
        lineCanvas!.position = CGPointZero
        lineContainer.addChild(lineCanvas!)
        lastPoint = CGPointMake(view.frame.size.width/2.0, view.frame.size.height/2.0)
    }

    // Returns a random value in the specified range
    func randomInRange(minValue:CGFloat, maxValue:CGFloat) -> CGFloat {
        let r = CGFloat(Double(arc4random_uniform(UInt32.max))/Double(UInt32.max))
        return (maxValue-minValue) * r + minValue
    }

    func drawLine() {
        if (CGPathIsEmpty(path)) {
            // Create a new line that starts where the previous line ended
            CGPathMoveToPoint(path, nil, lastPoint.x, lastPoint.y)
            lineNode.path = nil
            lineNode.lineWidth = 1.0
            lineNode.strokeColor = SKColor.blueColor()
            lineNode.zPosition = 100
            lineContainer.addChild(lineNode)
        }
        // Add a random line segment
        let x = randomInRange(size.width*0.1, maxValue: size.width*0.9)
        let y = randomInRange(size.height*0.1, maxValue: size.height*0.9)
        CGPathAddLineToPoint(path, nil, x, y)
        lineNode.path = path
        // Save the current point so we can connect the next line to the end of the last line
        lastPoint = CGPointMake(x, y)
    }

    override func update(currentTime: CFTimeInterval) {
        let lineDrawTime = timeScan / 10
        // 5. Draw a new line every 10 updates. Increment line count
        if (lineDrawTime != lastDrawTime) {
            drawLine()
            ++lineCount
        }
        // 6. and 7. Add all newly and previously drawn lines to the canvas
        if (lineCount == 8) {
            addLinesToTexture()
            lineCount = 0
        }
        lastDrawTime = lineDrawTime
        ++timeScan
    }

    func addLinesToTexture () {
        // Convert the contents of the line container to an SKTexture
        let texture = self.view!.textureFromNode(lineContainer)
        // Display the texture
        lineCanvas!.texture = texture
        // Start a new line
        lineNode.removeFromParent()
        path = CGPathCreateMutable()
    }
}
Другие вопросы по тегам