创建没有丢帧的无尽 cgpath [英] Create endless cgpath without framedrops
问题描述
我需要不断地创建一个 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:
- 创建一个
SKNode
用作行容器 - 创建一个将用作线条画布的
SKSpriteNode
- 创建一个
SKShapeNode
用于绘制新线 - 将容器添加到场景中,并将画布和形状节点添加到容器中
- 使用形状节点的
path
属性绘制一组相连的线段 - 当行数达到预定值时,将容器的内容转换为SKTexture"
- 将画布的纹理属性设置为
SKTexture
.请注意,由于画布也是容器的子对象,其内容也将添加到纹理中 - 起泡、冲洗、重复步骤 5 - 7
- Create an
SKNode
to be used as a line container - Create an
SKSpriteNode
that will be used as a line canvas - Create an
SKShapeNode
to be used to draw new lines - Add the container to the scene and the canvas and shape node to the container
- Draw a set of connected line segments using the
path
property of the shape node - When the line count reaches a predetermined value, convert the contents of the container to an 'SKTexture'
- 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 - 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屋!