2016-12-27 8 views
3

나는 작업중인 iOS 게임을위한 타일 맵을 만들고 있습니다. 지도는 섬을 위에서 내려다 본 모습입니다. 대부분의 타일은 물이지만 일부는 땅입니다. 물 타일은 물을 만들기 위해 재사용되지만 토지 타일은 모두 고유하기 때문에 두 번 이상 사용되지 않습니다. 내가 SKTileDefinition, SKTileGroup, SKTileGroupRule, SKTileSet 및 SKTileMap에 대한 문서를 통해 보았다, 그리고 이것이 내가 생각 해낸 것입니다 : 이제프로그래밍 방식으로 SpriteKit 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 툴을 사용하는 것을 피하고 완전히 프로그래밍 방식으로 맵을 생성하고 싶다. 이 코드는 작동하고 성능이 향상되었습니다 (처음에는 타일을 사용하지 않고 전체지도 이미지를 스크롤하는 것뿐이었습니다). 이것은 매우 추악하고 "이 작업을보다 간결하게해야합니다!"라는 비명을 지르는 것입니다. 내가 여기서 무엇을 놓치고 있니?

+1

일부'for' 루프는 어떻습니까? :) – jtbandes

+0

@jtbandes, 그게 처음으로 마음에 오는 솔루션이지만, 각 타일에 대한 변수와 각 타일에 대한 특정 행과 열이 있어야하므로 루프를 만드는 방법을 알지 못합니다. – SpacemanDeMars

+1

왜 각 타일에 변수가 필요합니까? 배열이나 사전에 저장할 수 없습니까? – jtbandes

답변

5

한 가지 방법은 특정 위치에 배치 할 타일을 지정하는 열과 행이있는 텍스트 파일에서지도 레이아웃을 정의하는 것입니다. 그런 다음 동일한 장면을 계속 사용하면서 각 게임 수준에 대해 다른지도를 지정할 수 있습니다. 이 예에서는 오직 하나의 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 파일로 만들어 첫 번째 코드 블록을 제거 할 수 있습니다.

많은 기능을 제공하기 때문에 SKTileMapNode으로 작업 할 때 GUI 도구를 사용하는 것이 좋습니다.

+2

이것은 이것에 대해 좋은 방법 인 것 같습니다. 가능하다면 모든 Xcode GUI 도구의 사용을 피하려고합니다. – SpacemanDeMars