title: Efficiently rendering tiled map using SpriteKit
body: <p>As an exercise, I decided to write a SimCity (original) clone in Swift for OSX. I started the project using SpriteKit, originally having each tile as an instance of <code>SKSpriteNode</code> and swapping the texture of each node when that tile changed. This caused terrible performance, so I switched the drawing over to regular Cocoa windows, implementing <code>drawRect</code> to draw <code>NSImage</code>s at the correct tile position. This solution worked well until I needed to implement animated tiles which refresh very quickly.</p>
  
  <p>From here, I went back to the first approach, this time using a texture atlas to reduce the amount of draws needed, however, swapping textures of nodes that need to be animated was still very slow and had a huge detrimental effect on frame rate.</p>
  
  <p>I'm attempting to display a 44x44 tile map where each tile is 16x16 pixels. I know here must be an efficient (or perhaps more correct way) to do this. This leads to my question:</p>
  
  <p>Is there an efficient way to support 1500+ nodes in SpriteKit and which are animated through changing their textures? More importantly, am I taking the wrong approach by using SpriteKit and <code>SKSpriteNode</code> for each tile in the map (even if I only redraw the dirty ones)? Would another approach (perhaps, OpenGL?) be better?</p>
  
  <p>Any help would be greatly appreciated. I'd be happy to provide code samples, but I'm not sure how relevant/helpful they would be for this question.</p>
  
  <p><strong>Edit</strong>
  Here are some links to relevant drawing code and images to demonstrate the issue:</p>
  
  <p>Screenshot:
  <img src="https://i.stack.imgur.com/iu5IO.png" alt="Swiftopolis"></p>
  
  <p>When the player clicks on the small map, the center position of the large map changes. An event is fired from the small map the central engine powering the game which is then forwarded to listeners. The code that gets executed on the large map the change all of the textures can be found here:</p>
  
  <p><a href="https://github.com/chrisbenincasa/Swiftopolis/blob/drawing-performance/Swiftopolis/GameScene.swift#L489" rel="nofollow noreferrer">https://github.com/chrisbenincasa/Swiftopolis/blob/drawing-performance/Swiftopolis/GameScene.swift#L489</a></p>
  
  <p>That code uses <code>tileImages</code> which is a wrapper around a Texture Atlas that is generated at runtime. </p>
  
  <p><a href="https://github.com/chrisbenincasa/Swiftopolis/blob/drawing-performance/Swiftopolis/TileImages.swift" rel="nofollow noreferrer">https://github.com/chrisbenincasa/Swiftopolis/blob/drawing-performance/Swiftopolis/TileImages.swift</a></p>
  
  <p>Please excuse the messiness of the code -- I made an alternate branch for this investigation and haven't cleaned up a lot of residual code that has been hanging around from pervious iterations.</p>