Apple 工作人员 Bobjt在这里表示,“正确的方法”是将用户数据添加到您的SKTileDefinition
对象中,并使用它来识别物理实体并将其添加到您的图块中。
因此,您可以通过编程方式或在编辑器中将用户数据值添加到磁贴定义中,如下所示:
然后在代码中,您将检查每个图块定义以查看它是否具有用户数据值。如果是这样,那么您需要计算 tile 的位置并在新节点上添加一个物理体,将其作为 tile map 的父级。这是 Bobjt 称为“正确方法”的代码:
self.tileMap = self.childNode(withName: "Tile Map") as? SKTileMapNode
guard let tileMap = self.tileMap else { fatalError("Missing tile map for the level") }
let tileSize = tileMap.tileSize
let halfWidth = CGFloat(tileMap.numberOfColumns) / 2.0 * tileSize.width
let halfHeight = CGFloat(tileMap.numberOfRows) / 2.0 * tileSize.height
for col in 0..<tileMap.numberOfColumns {
for row in 0..<tileMap.numberOfRows {
let tileDefinition = tileMap.tileDefinition(atColumn: col, row: row)
let isEdgeTile = tileDefinition?.userData?["edgeTile"] as? Bool
if (isEdgeTile ?? false) {
let x = CGFloat(col) * tileSize.width - halfWidth
let y = CGFloat(row) * tileSize.height - halfHeight
let rect = CGRect(x: 0, y: 0, width: tileSize.width, height: tileSize.height)
let tileNode = SKShapeNode(rect: rect)
tileNode.position = CGPoint(x: x, y: y)
tileNode.physicsBody = SKPhysicsBody.init(rectangleOf: tileSize, center: CGPoint(x: tileSize.width / 2.0, y: tileSize.height / 2.0))
tileNode.physicsBody?.isDynamic = false
tileNode.physicsBody?.collisionBitMask = playerCollisionMask | wallCollisionMask
tileNode.physicsBody?.categoryBitMask = wallCollisionMask
tileMap.addChild(tileNode)
}
}
}
就个人而言,我认为这种方法过于挑剔。我将在我的游戏中尝试不同的方法,如果可行,我会在这里发布。我真正想要的是让 Apple 增强瓦片地图 API,以便我们可以将物理实体直接添加到单个瓦片中。也许在此过程中,他们可以优化引擎,以便自动合并单个图块上的物理实体以形成更大、更优化的形状,从而提高系统性能。
更新:我就这个问题向 Apple提出了请求,不管它有什么好处。