7

我正在为我正在开发的 iOS 游戏创建平铺地图。该地图是一个岛屿的俯视图。大多数瓷砖是水,但有些是土地。水瓦被重复使用来创造水,但没有一个土地瓦被使用超过一次,因为所有土地瓦都是独一无二的。我查看了 SKTileDefinition、SKTileGroup、SKTileGroupRule、SKTileSet 和 SKTileMap 的文档,这就是我想出的:

func createTileMap() {
    let waterTile = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-1"))
    let waterTileGroup = SKTileGroup(tileDefinition: waterTile)

    let landTile64 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-64"))
    let landTile63 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-63"))
    let landTile56 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-56"))
    let landTile55 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-55"))
    let landTile54 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-54"))
    let landTile53 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-53"))
    let landTile48 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-48"))
    let landTile47 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-47"))
    let landTile46 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-46"))
    let landTile45 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-45"))
    let landTile44 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-44"))
    let landTile43 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-43"))
    let landTile40 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-40"))
    let landTile39 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-39"))
    let landTile37 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-37"))
    let landTile36 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-36"))
    let landTile35 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-35"))
    let landTile34 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-34"))
    let landTile31 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-31"))
    let landTile30 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-30"))
    let landTile27 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-27"))
    let landTile26 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-26"))
    let landTile25 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-25"))
    let landTile23 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-23"))
    let landTile22 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-22"))
    let landTile21 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-21"))
    let landTile20 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-20"))
    let landTile18 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-18"))
    let landTile17 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-17"))
    let landTile13 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-13"))
    let landTile12 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-12"))
    let landTile11 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-11"))
    let landTile3 = SKTileDefinition(texture: SKTexture(imageNamed: "map-tile-3"))

    let landTileGroupRule = SKTileGroupRule(adjacency: .adjacencyAll, tileDefinitions: [landTile64, landTile63, landTile56, landTile55, landTile54, landTile53, landTile48, landTile47, landTile46, landTile45, landTile44, landTile43, landTile40, landTile39, landTile37, landTile36, landTile35, landTile34, landTile31, landTile30, landTile27, landTile26, landTile25, landTile23, landTile22, landTile21, landTile20, landTile18, landTile17, landTile13, landTile12, landTile11, landTile3])

    let landTileGroup = SKTileGroup(rules: [landTileGroupRule])

    let tileSet = SKTileSet(tileGroups: [waterTileGroup, landTileGroup], tileSetType: .grid)

    tileMap = SKTileMapNode(tileSet: tileSet, columns: 8, rows: 8, tileSize: waterTile.size)
    tileMap.fill(with: waterTileGroup)

    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile64, forColumn: 7, row: 0)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile63, forColumn: 6, row: 0)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile56, forColumn: 7, row: 1)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile55, forColumn: 6, row: 1)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile54, forColumn: 5, row: 1)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile53, forColumn: 4, row: 1)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile48, forColumn: 7, row: 2)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile47, forColumn: 6, row: 2)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile46, forColumn: 5, row: 2)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile45, forColumn: 4, row: 2)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile44, forColumn: 3, row: 2)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile43, forColumn: 2, row: 2)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile40, forColumn: 7, row: 3)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile39, forColumn: 6, row: 3)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile37, forColumn: 4, row: 3)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile36, forColumn: 3, row: 3)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile35, forColumn: 2, row: 3)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile34, forColumn: 1, row: 3)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile31, forColumn: 6, row: 4)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile30, forColumn: 5, row: 4)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile27, forColumn: 2, row: 4)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile26, forColumn: 1, row: 4)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile25, forColumn: 0, row: 4)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile23, forColumn: 6, row: 5)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile22, forColumn: 5, row: 5)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile21, forColumn: 4, row: 5)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile20, forColumn: 3, row: 5)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile18, forColumn: 1, row: 5)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile17, forColumn: 0, row: 5)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile13, forColumn: 4, row: 6)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile12, forColumn: 3, row: 6)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile11, forColumn: 2, row: 6)
    tileMap.setTileGroup(landTileGroup, andTileDefinition: landTile3, forColumn: 2, row: 7)

    self.addChild(tileMap)
}

现在,这是非常粗略的代码,但我不确定我可以从这里去哪里。我正在加载每个土地板块,然后明确告诉它应该进入哪一列和哪一行。任何没有明确布局的板块都是水板块。我想避免为此使用任何 Xcode 的 GUI 工具,并完全以编程方式创建地图。这段代码有效,并且提高了性能(我最初只是在整个地图图像上滚动,而不是使用图块),它只是非常难看并且尖叫“必须有更简洁的方法来做到这一点!”。我在这里想念什么?

4

1 回答 1

8

一种方法是在文本文件中定义地图布局,其中包含指定在特定位置放置哪个图块的列和行。然后可以为每个游戏级别指定不同的地图,同时仍然使用相同的场景。此示例假设只有一个SKTileSet,并且不需要填充背景。

// Level1.txt
01 01 01 01 01 01 63 64
01 01 01 01 53 54 55 56
01 01 43 44 45 46 47 48
01 34 35 36 37 01 39 40
25 26 27 01 01 30 31 01
17 18 01 20 21 22 23 01
01 01 11 12 13 01 01 01
01 01 03 01 01 01 01 01

遍历每一列和每一行,检索指定的图块并调用setTileGroup.

let path = Bundle.main.path(forResource: "Level1.txt", ofType: nil)
do {
    let fileContents = try String(contentsOfFile:path!, encoding: String.Encoding.utf8)
    let lines = fileContents.components(separatedBy: "\n")

    for row in 0..<lines.count {
        let items = lines[row].components(separatedBy: " ")

        for column in 0..<items.count {
            let tile = tileMap.tileSet.tileGroups.first(where: {$0.name == "map-tile-" + items[column]})
            tileMap.setTileGroup(tile, forColumn: column, row: row)
        }
    }
} catch {
    print("Error loading map")
}

这消除了您示例中的第二个代码块。如果您想在使用 Xcode GUI 工具方面做出一些妥协,那么可以通过将第一个代码块创建SKTileGroupsks文件来消除。

我建议在使用时使用 GUI 工具SKTileMapNode,因为它们提供了很多功能。

于 2017-01-02T23:18:40.410 回答