Skip to content

Setting Up Your Scenes

Michael Fessenden edited this page Sep 21, 2017 · 4 revisions

Using Tiled assets in your projects is very straightforward with SKTiled. There are several tools included that allow you to easily access and customize content for your game.

SKTilemapDelegate Protocol

The SKTilemapDelegate protocol is provided to allow you to access (and change) your content as it is being created. It is recommended that your SpriteKit scenes conform to this protocol.

In addition to the callback methods, the protocol allows you to substitute your own classes for the default tile, vector and pathfinding objects.

protocol SKTilemapDelegate {
    func didBeginParsing(_ tilemap: SKTilemap)                      // Called when the map is instantiated.
    func didAddTileset(_ tileset: SKTileset)                        // Called when a tileset has been added.
    func didAddLayer(_ layer: SKTiledLayerObject)                   // Called when a layer has been added.
    func didReadMap(_ tilemap: SKTilemap)                           // Called before layers begin rendering.
    func didRenderMap(_ tilemap: SKTilemap)                         // Called when layers are finished rendering.
    func objectForTile(named: String?) -> SKTile.Type               // Tile object type for use with tile layers.
    func objectForVector(named: String?) -> SKTileObject.Type       // Vector object type for use with object groups.
    func objectForGraph(named: String?) -> GKGridGraphNode.Type     // Navigation graph node type.
}

Scene Setup

Setting up scenes is straightforward. Tile maps should be loaded during the SKScene.didMove(to:) method, and updated during the SKScene.update(_:) method.

A basic scene setup could be as simple as:

class GameScene: SKScene {
    var tilemap: SKTilemap!
    override func didMove(to view: SKView) {
        // load a named map
        if let tilemap = SKTilemap.load(tmxFile: "myTiledFile") {
            addChild(tilemap)
            // center the tilemap in the scene
            tilemap.position.x = (view.bounds.size.width / 2.0)
            tilemap.position.y = (view.bounds.size.height / 2.0)
            self.tilemap = tilemap
        }
    }

    override func update(_ currentTime: TimeInterval) {
        // update tilemap
        self.tilemap?.update(currentTime)
    }
}

If you choose to implement the SKTilemapDelegate protocol, you can utilize as many callback methods as you see fit (they are optional):

class GameScene: SKScene, SKTilemapDelegate {
    var tilemap: SKTilemap!
    override func didMove(to view: SKView) {
        if let tilemap = SKTilemap.load(fromFile: "myTiledFile", delegate: self) {
            // add the tilemap to the scene
            addChild(tilemap)
            // center the tilemap in the scene
            tilemap.position.x = (view.bounds.size.width / 2.0)
            tilemap.position.y = (view.bounds.size.height / 2.0)
            self.tilemap = tilemap
        }
    }

    override func update(_ currentTime: TimeInterval) {
        // update tilemap
        self.tilemap?.update(currentTime)
    }

    func didAddTileset(_ tileset: SKTileset) {
        if (tileset.type == "Summer") {
            tileset.type = "Winter"
        }
    }

    func didRenderMap(_ tilemap: SKTilemap) {
        // finish setting up map here
        if let obstaclesLayer = tilemap.objectGroup(named: "Obstacles") {
            obstaclesLayer.isHidden = true
            obstaclesLayer.setupPhysics()
        }
    }
}

Custom Tile Objects

It is possible to use your own custom tile sprite objects in your projects. Subclass the built-in SKTile object and make it available in your scenes allows you to use different tile type for different scenes.

class MainMenuScene: SKScene, SKTilemapDelegate {
    func objectForTile(named: String?) -> SKTile.Type {
        return MenuButtonTile.self
    }
}

Demo Scene

Project Targets

The included demo scene conforms to the SKTiledSceneDelegate protocol. This protocol outlines a standard game scene setup with a camera that interacts with your tilemaps. The included SKTiledScene class conforms to this protocol and can serve as a template, though you are free to implement your own setups.

Scene Hierarchy

public protocol SKTiledSceneDelegate: class {
    /// Root container node. Tiled assets are parented to this node.
    var rootNode: SKNode! { get set }
    /// Custom scene camera.
    var cameraNode: SKTiledSceneCamera! { get set }
    /// Tile map node.
    var tilemap: SKTilemap! { get set }
    /// Load a tilemap from disk, with optional tilesets
    func load(tmxFile: String, inDirectory: String?, withTilesets tilesets: [SKTileset], ignoreProperties: Bool, buildGraphs: Bool, loggingLevel: LoggingLevel) -> SKTilemap?
}

The tilemap is parented to a root container node, which interacts with the included SKTiledSceneCamera object and allows you to easily navigate the scene with mouse & touch events. The root node is set to 0,0 in the scene by default.

Calling the class method SKTilemap.load(tmxFile:) will initialize a parser to read the file name given.

To see the SKTiledScene in action, compile one of the demo targets and look at the SKTiledDemoScene class.

Loading External Content

The demo project allows you to load and test your own Tiled content (macOS only). Simply compile the macOS demo target and load map from the File menu.

Loading External