I have managed to load and display an isometric map using SpriteKit and Swift by writing my own .TMX parser. Orthogonal maps work fine, but this is my first time using Isometric maps and the math is confusing me.
My tiles are 64x32, and the map can be any size.
Ideally I would like the left most edge of the map (the tile at [0, maxRow]) to be sitting at zero on the x-axis, and the bottom most edge of the may (the tile at [maxCol, maxRow]) to be sitting on the 0 y-axis.
The origin of the map is the tile at the top. X goes from Top to Right, Y goes from Top to Left.
SpriteKit also has a reversed y-axis. The code below is how i am positioning tiles based on their coords, and retrieving them using a position on screen. This code works fine.
So to offset the position correcting so I can place the map where I want I need to be able to find the width and height of an isometric map of any size and I have no idea where to start.
func positionForCoord(col: Int, _ row: Int) -> (x: CGFloat, y: CGFloat) {
var x: CGFloat = 0
var y: CGFloat = 0
x = (CGFloat(col - row) * CGFloat(tileSize.width)) / 2
y = (CGFloat(col + row) * -CGFloat(tileSize.height)) / 2
return (x, y)
}
func coordForPosition(x: CGFloat,_ y: CGFloat) -> (col: Int, row: Int) {
var col: Int = 0
var row: Int = 0
let tileWidthHalved = CGFloat(tileSize.width) / 2
let tileHeightHalved = CGFloat(tileSize.height) / 2
col = Int(floor(((x / tileWidthHalved) - ((y - tileHeightHalved) / tileHeightHalved)) / 2))
row = Int(ceil(((((y - tileHeightHalved) / -tileHeightHalved) - (x / tileWidthHalved)) / 2)))
return (col, row)
}