我需要不断创建一个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)
但问题是,随着时间的推移,帧越来越低。有什么我必须改变,以便帧率不再下降?
我的目标是创造一条随机的无尽路径。
答案 0 :(得分:4)
在绘制逐渐增加的行数时保持高FPS计数的关键是快速达到向场景添加更多行对帧速率影响很小或没有影响的状态。至少有两种方法可以实现这一目标。
两者中最直接的方法是定期将先前绘制的线转换为SKTexture
,并将结果显示为SKSpriteNode
的纹理。以下是步骤:
SKNode
以用作行容器SKSpriteNode
SKShapeNode
path
属性SKTexture
。请注意,由于画布也是容器的子画面,其内容也将添加到纹理 这是Swift中的一个示例实现,它在iPhone 6设备上以60 FPS绘制无穷无尽的行(您应该在不使用模拟器的设备上测试性能):
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()
}
}