gpt4 book ai didi

ios - TileMap 集中的自定义组未选择正确的图 block

转载 作者:行者123 更新时间:2023-12-01 16:08:07 49 4
gpt4 key购买 nike

我用周围瓷砖的所有可能组合制作了一个自定义组。

Custom group screenshot

我将它与我的 TileMap 上启用的自动映射模式一起使用,结果如下:

Render in the editor

如您所见,有几个错误:

Annotated render (green = proper tile, red = wrong tile)

我以编程方式和在编辑器中都尝试过。行为是相同的。

我的想法是自动映射引擎在处理角落(左上方,右下方)时采用第一个匹配元素。以下是一些错误,与引擎应该采用的元素相关联:

Annotated tiles

所有错误的都在匹配的瓷砖之前。但是我找不到任何方法来重新排序图 block 来测试这个理论(在编辑器中,甚至在配置文件中,因为组在二进制文件中)。

有没有办法解决这个问题?

在此先感谢您的时间。

编辑

我试图删除并重新创建一些错误的图 block ,它证实了这个理论:在处理角度时,自动映射引擎会采用第一个匹配元素,即使它们中的角被禁用。它不会检查是否有更好的瓷砖匹配角规则。

问题保持不变:有没有办法纠正这种行为,还是我必须编写自动映射引擎代码?

最佳答案

我已经为此工作了 2 周。我在使用 SpriteKit SKTileMapNode 自动平铺时遇到了一些严重问题。我关注了this article并弄清楚我需要做什么才能获得正确的自动平铺。我在互联网上翻遍了旧论坛和网站,试图拼凑出这篇文章所解释的确切内容。

最后,经过数周的测试和无数次尝试/错误,我想出了一段功能代码,它模拟了 SpriteKit 中自动平铺应该做的事情。

// Auto-tiling tool to bypass the auto-mapping in SpriteKit.
// This tool opens up a lot more options than the one provided by SpriteKit
class TileData {

var map:SKTileMapNode
var column:Int
var row:Int
//var array2D = [[Int]]()

init(Column: Int, Row: Int, Map: SKTileMapNode) {
column = Column
row = Row
map = Map
}

func returnTileData(C: Int, R: Int) -> Int {
var directions = 0
if map.tileGroup(atColumn: C, row: R) == tileGroups[48] {
if map.tileGroup(atColumn: C - 1, row: R + 1) == tileGroups[48] {
directions += 1
}
if map.tileGroup(atColumn: C, row: R + 1) == tileGroups[48] {
directions += 2
}
if map.tileGroup(atColumn: C + 1, row: R + 1) == tileGroups[48] {
directions += 4
}
if map.tileGroup(atColumn: C - 1, row: R) == tileGroups[48] {
directions += 8
}
if map.tileGroup(atColumn: C + 1, row: R) == tileGroups[48] {
directions += 16
}
if map.tileGroup(atColumn: C - 1, row: R - 1) == tileGroups[48] {
directions += 32
}
if map.tileGroup(atColumn: C, row: R - 1) == tileGroups[48] {
directions += 64
}
if map.tileGroup(atColumn: C + 1, row: R - 1) == tileGroups[48] {
directions += 128
}
}
let east = (directions & Dir.East.rawValue) == Dir.East.rawValue
let west = (directions & Dir.West.rawValue) == Dir.West.rawValue
let south = (directions & Dir.South.rawValue) == Dir.South.rawValue
let north = (directions & Dir.North.rawValue) == Dir.North.rawValue
let northEast = (directions & Dir.NorthEast.rawValue) == Dir.NorthEast.rawValue
let northWest = (directions & Dir.NorthWest.rawValue) == Dir.NorthWest.rawValue
let southEast = (directions & Dir.SouthEast.rawValue) == Dir.SouthEast.rawValue
let southWest = (directions & Dir.SouthWest.rawValue) == Dir.SouthWest.rawValue

return getTileData(east: east, west: west, north: north, south: south,
northWest: northWest, northEast: northEast, southWest:southWest, southEast: southEast)
}

func getTileData(east: Bool, west: Bool, north: Bool, south: Bool, northWest: Bool, northEast: Bool, southWest: Bool, southEast: Bool) -> Int {
var directions = (east ? Dir.East.rawValue : 0) | (west ? Dir.West.rawValue : 0) | (north ? Dir.North.rawValue : 0) | (south ? Dir.South.rawValue : 0)

directions |= ((north && west) && northWest) ? Dir.NorthWest.rawValue : 0
directions |= ((north && east) && northEast) ? Dir.NorthEast.rawValue : 0
directions |= ((south && west) && southWest) ? Dir.SouthWest.rawValue : 0
directions |= ((south && east) && southEast) ? Dir.SouthEast.rawValue : 0

return directions
}
}

我将尝试准确解释它的作用以及如何使其工作。

该算法首先用数据填充第一张 map 。它采用自定义类,传入列、行和第一个预填充 map 。它检查第一个 map 中每个瓦片的邻居,根据它返回一个位掩码,并根据返回的位掩码将一个瓦片设置到第二个 map 中。

这是整个过程。当然,它可能会得到改进。但这需要时间。
// There are 47 possible tile orientations.
let tileBits = [2, 8, 10, 11, 16, 18, 22, 24, 26, 27,
30, 31, 64, 66, 72, 74, 75, 80, 82, 86,
88, 90, 91, 94, 95, 104, 106, 107, 120,
122, 123, 126, 127, 208, 210, 214, 216, 218,
219, 222, 223, 248, 250, 251, 254, 255, 0]

// Because of how buggy SKTileMapNodes currently are, two tile maps are needed for this process

let tileMap = SKTileMapNode(tileSet: tileSet, columns: columns, rows: rows, tileSize: tileSize)
let tileMap2 = SKTileMapNode(tileSet: tileSet, columns: columns, rows: rows, tileSize: tileSize)

for c in 0..<tileMap.numberOfColumns {
for r in 0..<tileMap.numberOfRows {
// Fill your first tile map in here.
// Pretty standard stuff.
}
}

for c in 0..<tileMap2.numberOfColumns {
for r in 0..<tileMap2.numberOfRows {
// Assign variable to the class and pass in the pre-filled tileMap
let tile = TileData(Column: c, Row: r, Map: tileMap)

// Get the bit-mask of the tile at (column, row)
let number = tile.returnTileData(C: c, R: r)

// If the array of tileBits contains the bitmask
if tileBits.contains(number) {
// Find out where it is at in the array

guard let bit = tileBits.firstIndex(of: number) else { return }

// Set the Tile Group
tileMap2.setTileGroup(tileGroups[bit], forColumn: c, row: r)
}
}
}
// tileMap.setScale(0.2)
self.addChild(tileMap2)

有 47 种可能的瓷砖排列方式。基本上,您必须创建一个包含 48 个图 block 组的数组。 1-47 是可能的瓷砖方向。 48 代表第一张 map 中的填充空间。另一个数组存储所有 47 个位掩码,用于可能的图 block 方向。它采用返回的位掩码并将其与该数组进行比较以找到它所在的索引。然后它访问瓦片组数组并根据位掩码数组的索引将瓦片设置到第二个瓦片映射中。

希望这是有道理的。

这是瓦片 Sprite-sheet,每个瓦片从左到右排列,从最小到最大。

2, 8, 10, 11, 16, 18, 22, 24, 26, 27, 30, 31, 64, 66, 72, 74, 75, 80, 82, 86, 88, 90, 91, 94, 95, 104、106、107、120、122、123、126、127、208、210、214、216、218、219、222、223、248、250、251、254、255、0

Image 1

关于ios - TileMap 集中的自定义组未选择正确的图 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52198373/

49 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com