Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programmatically create SKTileMapNode in Swift

does anyone know how to create an SKTileMapNode programmatically using Swift please? (NOTE: I do not want to do this using the editor, I want to achieve this programmatically only)

I have tried the following but does not render my tile map

let bgTexture = SKTexture(imageNamed: "background")
let bgDefinition = SKTileDefinition(texture: bgTexture, size: bgTexture.size())
let bgGroup = SKTileGroup(tileDefinition: bgDefinition)
let tileSet = SKTileSet(tileGroups: [bgGroup])
let bgNode = SKTileMapNode(tileSet: tileSet, columns: 5, rows: 5, tileSize: bgTexture.size())
bgNode.position = CGPoint(x: self.frame.size.width / 2, y: self.frame.size.height / 2)
bgNode.setScale(1)
self.addChild(bgNode)

Any help greatly appreciated

like image 667
Neil Stevens Avatar asked Sep 16 '16 14:09

Neil Stevens


2 Answers

To layout the entire map with the single background tile you would iterate through each column and each row. You'll need to retrieve the background tile first.

let tile = bgNode.tileSet.tileGroups.first(
    where: {$0.name == "background"})

for column in 0..4 {
    for row in 0..4 {
        bgNode.setTileGroup(tile, forColumn: column, row: row)
    }
}

There is also a convenience function to achieve a flood fill;

bgNode.fill(with: tile)

There is also an initialiser for SKTilemapNode that accepts SKTileGroup

let bgNode = SKTileMapNode(tileSet: tileSet, columns: 5, rows: 5, tileSize: bgTexture.size(), fillWithTileGroup: tile)

I strongly recommend to leverage the functionality built into Xcode for creating TileSets and TileMaps. You can still programatically fill the map.

like image 194
Mark Brownsword Avatar answered Sep 22 '22 09:09

Mark Brownsword


In case it's helpful to anyone, here's the whole thing put together:

class MyGameScene: SKScene {
    override func didMove(to view: SKView) {
        guard let tileSet = SKTileSet(named: "testset") else {
            // hint: don't use the filename for named, use the tileset inside
            fatalError()
        }

        let tileSize = tileSet.defaultTileSize // from image size
        let tileMap = SKTileMapNode(tileSet: tileSet, columns: 5, rows: 5, tileSize: tileSize)
        let tileGroup = tileSet.tileGroups.first
        tileMap.fill(with: tileGroup) // fill or set by column/row
        //tileMap.setTileGroup(tileGroup, forColumn: 5, row: 5)
        self.addChild(tileMap)
    }
}
like image 30
zekel Avatar answered Sep 22 '22 09:09

zekel