创建没有丢帧的无尽 cgpath [英] Create endless cgpath without framedrops

查看:25
本文介绍了创建没有丢帧的无尽 cgpath的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要不断地创建一个 cgpath.目前我是这样做的:

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

 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)

但问题是,随着时间的推移,帧数会越来越低.有什么我必须改变的,以使帧率不再下降吗?

But the problem is, that the frames drop lower and lower over time. Is there something I have to change so that the framerate no longer drops?

我的目标是创建一条随机的无限路径.

My goal is to create a random endless path.

推荐答案

在绘制线数逐渐增加的同时保持高 FPS 计数的关键是快速达到向场景添加更多线很少或没有的状态对帧率的影响.至少有两种方法可以做到这一点.

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.

两者中最直接的方法是定期将先前绘制的线条转换为 SKTexture 并将结果显示为 SKSpriteNode 的纹理.步骤如下:

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. 创建一个 SKNode 用作行容器
  2. 创建一个将用作线条画布的 SKSpriteNode
  3. 创建一个 SKShapeNode 用于绘制新线
  4. 将容器添加到场景中,并将画布和形状节点添加到容器中
  5. 使用形状节点的path属性绘制一组相连的线段
  6. 当行数达到预定值时,将容器的内容转换为SKTexture"
  7. 将画布的纹理属性设置为SKTexture.请注意,由于画布也是容器的子对象,其内容也将添加到纹理中
  8. 起泡、冲洗、重复步骤 5 - 7
  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

这是一个在 Swift 中的示例实现,它在 iPhone 6 设备上以 60 FPS 的速度绘制无穷无尽的线条(您应该在不使用模拟器的设备上测试性能):

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()
    }
}

这篇关于创建没有丢帧的无尽 cgpath的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆