Create endless cgpath without framedrops

后端 未结 1 1321
栀梦
栀梦 2021-01-17 21:40

I need to create a cgpath continuously. At the moment I do it like that:

 func createLine(){
        var rand = randomBetweenNumbers(1, 2)
        currentY--         


        
相关标签:
1条回答
  • 2021-01-17 22:36

    The key to maintaining a high FPS count while drawing a progressively increasing number of lines is to quickly reach a state where adding more lines to the scene has little or no effect on frame rate. There are at least two ways to accomplish this.

    The most straightforward of the two is to periodically convert the previously drawn lines to an SKTexture and display the results as texture of an SKSpriteNode. Here are the steps:

    1. Create an SKNode to be used as a line container
    2. Create an SKSpriteNode that will be used as a line canvas
    3. Create an SKShapeNode to be used to draw new lines
    4. Add the container to the scene and the canvas and shape node to the container
    5. Draw a set of connected line segments using the path property of the shape node
    6. When the line count reaches a predetermined value, convert the contents of the container to an 'SKTexture'
    7. Set the texture property of the canvas to the SKTexture. Note that since the canvas is also a child of the container, its contents will also be added to the texture
    8. Lather, rinse, repeat steps 5 - 7

    Here's an example implementation in Swift that draws an endless set of lines at 60 FPS on an iPhone 6 device (you should test performance on a device not with the simulator):

    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()
        }
    }
    
    0 讨论(0)
提交回复
热议问题