I have the following code to draw a picture in an SKScene:
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
newPoint = location
let pathToDraw:CGMutablePathRef = CGPathCreateMutable()
let myLine:SKShapeNode = SKShapeNode(path:pathToDraw)
CGPathMoveToPoint(pathToDraw, nil, lastPoint.x, lastPoint.y)
CGPathAddLineToPoint(pathToDraw, nil, newPoint.x, newPoint.y)
lastPoint = newPoint
myLine.lineWidth = 3.0
myLine.path = pathToDraw
myLine.strokeColor = SKColor.whiteColor()
self.addChild(myLine)
}
}
This does what I want, I can draw with it but I do not think it is very efficient. Should I use an alternate method to get the same effect of drawing a picture or is this okay? If I should use something else, what would the alternate method be?
Rather add an "SKShapeNode" as your drawing node and have it's path as a property i.e.
class MyDrawingNode: SKNode {
...
}
and update the path rather than adding individual SKNode children per line to point in the path. So something to the effect of:
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
newPoint = location
let myLinePath:CGMutablePathRef = myDrawingNode.path
...
}
*edit: *The difference here being that you're only manipulating one
object, and that is the path.. In your case you were creating many objects
... Think of the outline of a house:
In this example, I've labelled each portion
of the path.
The 1
above, is more efficient in terms of memory and cpu/gpu use. 2
above is heftier on the cpu/gpu and memory, but them allows you to individually manipulate each part of the path individually.
If the concept of 2
above is what you're after, i.e. referring to each part of the path individually, rather:
SKHouseNode
leftRoofPath, rightRoofPath, rightVertPath, bottomHorzPath, leftVertPath
perhaps as a struct and put it all together with:struct HousePathComponent { var startPoint: CGPoint var endPoint: CGPoint var lineThickness: CGFloat } typealias HousePath = [HousePathComponent]
var myHouse = HousePath()
var leftVertPath = HousePathComponent(startPoint: CGPointMake(0.0,0.0), endPoint: CGPointMake(0.0,100.0), lineThickness: 1.0)
var leftRoofNode = HousePathComponent(startPoint: CGPointMake(0.0,100.0), endPoint: CGPointMake(50.0,150.0), lineThickness: 1.0)
var rightRoofNode = HousePathComponent(startPoint: CGPointMake(50.0,150.0), endPoint: CGPointMake(100.0,100.0), lineThickness: 1.0)
var rightVert = HousePathComponent(startPoint: CGPointMake(100.0,100.0), endPoint: CGPointMake(100.0,0.0), lineThickness: 1.0)
var bottomHorz = HousePathComponent(startPoint: CGPointMake(100.0,0.0), endPoint: CGPointMake(0.0,0.0), lineThickness: 1.0)
myHouse.appendContentsOf([leftVertPath, leftRoofNode, rightRoofNode, rightVert, bottomHorz])
From here draw the path using the contents of myHouse
which is an array of the various structs.
There are loads of ways you can approach this, so I'm just throwing rough ideas out there for you to toy with :)
FPS Dropping
One way about this would be to:
In the SKScene
in the update function, put some code together to only update the scene every x ms as opposed to every pass with something like:
var nthFrameCount = 0 let nthFrame = 6 override func update(currentTime: CFTimeInterval) {
hero.tileSpriteIso.position = point2DToIso(hero.tileSprite2D.position)
nthFrameCount += 1
if (nthFrameCount == nthFrame) {
nthFrameCount = 0
updateOnNthFrame()
}
}
then handle the actual update code in the updateOnNthFrame
function. So in the above example, it'd be every 6 frames as opposed to every frame.
Although less will be drawing per ms of time, the human eye starts registering smooth motion
from about 25~30fps... On a television, in the US the television analog standard is NTSC, and that was 30 fps.
So as you update your movements less times per second, the actual times the "update code" is run is 10 times per second (in my example, 10 times / second if the FPS is 60 fps)...
Hope this explains a little more :) If not, pop me a chat request and I'll try help you further!
Cheers :)