代码之家  ›  专栏  ›  技术社区  ›  E. Huckabee

在给定4个角点位置时,编写填充平铺图的算法时遇到问题

  •  1
  • E. Huckabee  · 技术社区  · 6 年前

    let mapWidth = 225
    let mapHeight = 150
    
    var tileMap = SKTileMapNode()
    
    var rooms = [Room]()
    
    class Room {
        // these values hold grid coordinates for each corner of the room
        var x1:Int
        var x2:Int
        var y1:Int
        var y2:Int
    
        var width:Int
        var height:Int
    
        // center point of the room
        var center:CGPoint
    
        init (x:Int, y:Int, w:Int, h:Int) {
    
            x1 = x
            x2 = x + w
            y1 = y
            y2 = y + h
            width = w
            height = h
            center = CGPoint(x: ((x1 + x2) / 2),
                             y: ((y1 + y2) / 2))
        }
        func intersects(room:Room) -> Bool {
            if x1 <= room.x2 && x2 >= room.x1 && y1 <= room.y2 && y2 >= room.y1 {
                return true
            } else {
                return false
            }
        }
    }
    

    这是我用来确定房间大小、四个角的坐标以及房间在tileMap网格中的位置的代码片段。

    this article .

    继续本文,我从room generator收集信息,并将其放置到一个数组中,这样我就可以在tileMap中划分出房间。

    func placeRooms() {
    
        let numberOfRooms = Int(arc4random_uniform(20) + 10)
    
        for i in 0..<numberOfRooms {
            let w = Int(arc4random_uniform(15) + 5);
            let h =  Int(arc4random_uniform(15) + 5);
            let x = Int(arc4random_uniform(UInt32(mapWidth)));
            let y = Int(arc4random_uniform(UInt32(mapHeight)));
    
            // create room with randomized values
            let newRoom = Room(x:x, y:y, w:w, h:h);
    
            var failed = false
            for otherRoom in rooms {
                if newRoom.intersects(room: otherRoom) {
                    failed = true
                }
            }
            if failed == false {
                rooms.append(newRoom)
            }
        }
        createRooms()
    }
    

    但现在我开始使用所有的信息来划分tileMap中的房间。我有四个角落的位置,我只需要知道如何填写他们之间的一切。到目前为止,我得到的是:

    func createRooms() {
        let tile1 = SKTexture(imageNamed: "black")
        let tile2 = SKTexture(imageNamed: "gray")
    
        let black = SKTileGroup(tileDefinition: SKTileDefinition(texture: tile1, size: CGSize(width: 32, height: 32)))
        let gray = SKTileGroup(tileDefinition: SKTileDefinition(texture: tile2, size: CGSize(width: 32, height: 32)))
    
        let tileSet = SKTileSet(tileGroups: [gray,black])
    
        tileMap = SKTileMapNode(tileSet: tileSet, columns: mapWidth, rows: mapHeight, tileSize: CGSize(width: 32, height: 32))
    
        for c in 0..<tileMap.numberOfColumns {
            for r in 0..<tileMap.numberOfRows  {
                for i in 0..<rooms.count {
                    if rooms[i].x1 <= c && rooms[i].x2 >= c && rooms[i].y1 <= r && rooms[i].y2 >= r {
                        tileMap.setTileGroup(gray, forColumn: c, row: r)
                        print("Room Tile")
                    }
                    if tileMap.tileGroup(atColumn: c, row: r) != gray {
                        tileMap.setTileGroup(black, forColumn: c, row: r)
                    }
                }
            }
        }
        self.addChild(tileMap)
        tileMap.setScale(0.05)
    }
    

    编辑: ^^这是你唯一需要关注的部分,以防你感到不知所措。我只需要知道如何取4个角点坐标,并填充其间的所有内容。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Steve G.    6 年前

    您可以解析这些房间,对于每个房间,使用坐标解析瓷砖。

    比如:

    for room in rooms {
      for column in room.x1...(room.x1 + room.width) {
        for row in room.y1...(room.y1 + room.height) {
          tileMap.setTileGroup(tile1, forColumn: column, row: row) 
        }
      }
    }
    

    而不是储存 x1 , y1 x2 , y2 height width ,您可以使用 CGRect (或基于它的自定义结构)。你只需要一个原点和一个尺寸(也许 column , row 宽度 , 高度 ?).

        2
  •  0
  •   E. Huckabee    6 年前

    我想出来了。我使用了检查相交房间的相同代码,根据四个角确定每个房间的位置,然后填充中间的所有内容。

    func createRooms() {
    let tile1 = SKTexture(imageNamed: "black")
    let tile2 = SKTexture(imageNamed: "gray")
    
    let black = SKTileGroup(tileDefinition: SKTileDefinition(texture: tile1, size: CGSize(width: 32, height: 32)))
    let gray = SKTileGroup(tileDefinition: SKTileDefinition(texture: tile2, size: CGSize(width: 32, height: 32)))
    
    let tileSet = SKTileSet(tileGroups: [gray,black])
    
    tileMap = SKTileMapNode(tileSet: tileSet, columns: mapWidth, rows: mapHeight, tileSize: CGSize(width: 32, height: 32))
    
    for c in 0..<tileMap.numberOfColumns {
        for r in 0..<tileMap.numberOfRows  {
            for i in 0..<rooms.count {
                if rooms[i].x1 <= c && rooms[i].x2 >= c && rooms[i].y1 <= r && rooms[i].y2 >= r {
                    tileMap.setTileGroup(gray, forColumn: c, row: r)
                }
                if tileMap.tileGroup(atColumn: c, row: r) != gray {
                    tileMap.setTileGroup(black, forColumn: c, row: r)
                }
            }
        }
    }
    

    Image 1

    Image 2

    Image 3

    我的下一个目标是找出如何将它们与走廊连接起来。

    推荐文章