Reputation: 4951
This is for a puzzle game. As you can see from the screenshot, there are 256 nodes on screen and frame rate hovers around 10 FPS.
I see plenty of puzzle games out there with what I assume amounts to hundreds of separate nodes on screen, yet with great frame rates... I'd like to achieve the same. What are some optimization points I can consider based on my code? (Drawing code below)
I'm literally just creating a bunch of SKShapeNodes, putting them into an NSArray, and then adding them as children to the scene on didMoveToView
class GameScene: SKScene {
var grid: Grid! = nil
override func didMoveToView(view: SKView) {
self.grid = Grid()
self.grid.initWithParent(parent: self, rows:16, columns:8, hexagonSize:40.0)
self.grid.drawGrid()
}
override func update(currentTime: CFTimeInterval)
{
// nothing here!! why so slow..
}
}
//…
class Grid : NSObject {
// this all gets initialized later
var hexagonSize: CGFloat! = nil
var hexagonArray: NSMutableArray! = nil
var numRows: Int! = nil
var numColumns: Int! = nil
var parentScene: SKScene? = nil
// …
func drawGrid(){
//…
if(self.parentScene != nil){
for rowIdx in 0..<self.numRows {
for colIdx in 0..<self.numColumns {
//…
let hex = Hexagon()
hex.initWithParentNode(node: self.parentScene!, size: self.hexagonSize)
hex.drawAtPoint(positionPoint: hexCenter)
self.hexagonArray.addObject(hex) hex.drawAtPoint(:positionPoint)
}
}
}
}
func initWithParent(#parent: SKScene, rows: Int, columns: Int, hexagonSize: CGFloat){
self.parentScene = parent
self.numRows = rows
self.numColumns = columns
self.hexagonSize = hexagonSize
}
}
//…
class Hexagon: NSObject {
//…
var parentNode : SKNode? = nil
var size : CGFloat! = nil
var shape : SKShapeNode! = nil
func drawAtPoint(#positionPoint: CGPoint){
let diameter = self.size
let radius = diameter/2
let normal = radius * sqrt(3)/2
var path = CGPathCreateMutable()
self.shape = SKShapeNode(path: path)
let point = CGPointZero
CGPathMoveToPoint(path, nil, point.x, point.y+radius)
CGPathAddLineToPoint(path, nil, point.x+normal, point.y+(radius/2))
CGPathAddLineToPoint(path, nil, point.x+normal, point.y-(radius/2))
CGPathAddLineToPoint(path, nil, point.x, point.y-(diameter/2))
CGPathAddLineToPoint(path, nil, point.x-normal, point.y-(radius/2))
CGPathAddLineToPoint(path, nil, point.x-normal, point.y+(radius/2))
CGPathAddLineToPoint(path, nil, point.x, point.y+radius)
self.shape?.path = path
self.shape?.fillColor = SKColor.blueColor()
if(self.shape != nil && self.parentNode != nil){
self.shape.position = positionPoint
self.parentNode!.addChild(self.shape!)
}
}
func initWithParentNode(#node: SKNode, size: CGFloat){
self.parentNode = node
self.size = size
}
}
Upvotes: 3
Views: 635
Reputation: 59506
Well... you are manually drawing on the screen... You should leave to the SpriteKit engine the responsibility to draw your sprites on the screen (it has tons of optimizations to do this better then we can usually do).
First of all throw away your classes Grid
and Hexagon
.
Done? Good :)
hexagon.png
(I prepared the image for you)Xcode Asset catalog
Create a file Hexagon.swift
and write into it the following code
import SpriteKit
class Hexagon : SKSpriteNode {
init() {
let texture = SKTexture(imageNamed: "hexagon")
super.init(texture: texture, color: UIColor.clearColor(), size: texture.size())
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Now it's just a matter of creating a few Hexagon(s)
and placing them on your scene.
class GameScene: SKScene {
override func didMoveToView(view: SKView) {
let hexagon0 = Hexagon()
hexagon0.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame))
self.addChild(hexagon0)
// add more Hexagon(s) at different positions...
}
}
That's it. SpriteKit will take care of drawing the sprites you added to the scene.
Following this approach you can add a huge number of sprites on the screen, SpriteKit will do optimizations we mortal human beings will never know to keep the framerate as high as possible.
(The optimizations will be even better with Xcode 7 and iOS 9 since SpriteKit is now built on top of Metal).
Hope this helps.
Upvotes: 7