Trying to make an isometric grid programmatically with Swift
The only reason I am trying to do this programmatically is to access the location of each tile, allowing the grid to be manipulated. I have looked at about 15 different tutorials using other programming languages, but even with this knowledge it is still very difficult for me to create one in Swift.
I tried to create a nested loop for the loop, but I'm not even sure if the code inside the loops is logical to create an isometric grid, I just pulled it off from one of the tutorials I found:
func generateGrid() {
for (var i = 0; i < 5; i++) {
for (var j = 5; j >= 0; j--){
tile.position = CGPoint(x: (j * Int(tile.size.height) / 2) +
(i * Int(tile.size.width) / 2),
y: (i * Int(tile.size.height) / 2) -
(j * Int(tile.size.width) / 2))
addChild(tile)
}
}
}
Then I tried to call this in the "didMoveToView" function, but obviously you cannot add the same node more than once.
Please give me any direction you can.
source to share
Here's an example of creating an isometric grid in SpriteKit:
Define mesh parameters
let tileHeight:CGFloat = 16.0
let tileWidth:CGFloat = 32.0
let numRows = 5
let numCols = 6
Create grid items and add them to the scene at the appropriate locations
let size = CGSizeMake(tileWidth, tileHeight)
for row in 1...numRows {
for col in 1...numCols {
// Create a new tile object
let tile = newTile(size)
// Convert (col,row) to (x,y)
tile.position = tilePosition(col, row: row)
self.addChild(tile)
}
}
This function converts the grid position to scene x and y coordinates. Use this to create a grid and add buildings to the grid.
func tilePosition(col:Int, row:Int) -> CGPoint {
let x = (CGFloat(row) * tileWidth / 2.0) + (CGFloat(col) * tileWidth / 2.0)
let y = (CGFloat(col) * tileHeight / 2.0) - (CGFloat(row) * tileHeight / 2.0)
return CGPointMake(x+100.0, y+100.0)
}
This function creates a new diamond shape SKShapeNode
func newTile(size:CGSize) -> SKShapeNode {
let shape = SKShapeNode()
let path = UIBezierPath()
path.moveToPoint(CGPointMake(0, size.height / 2.0))
path.addLineToPoint(CGPointMake(size.width / 2.0, 0))
path.addLineToPoint(CGPointMake(0, -size.height / 2.0))
path.addLineToPoint(CGPointMake(-size.width / 2.0, 0))
path.closePath()
shape.path = path.CGPath
shape.lineWidth = 1.0
shape.fillColor = SKColor.grayColor()
return shape
}
This function determines the appropriate z position to ensure that buildings placed on the grid are displayed in the correct order.
func buildingZPosition(col:Int, row:Int) -> CGFloat {
return CGFloat(row*numCols + numCols-col)
}
Figure 1. Isometric grid created using the above code
source to share
To create such an isometric grid
you need to create two loops. One of them iterates through rows and the other iterates through columns. Note that the center of every other column is shifted by half the height of the tile and is the same for every other row. To compensate for this, we check if the rows and columns are even or odd and adjust them accordingly. A potential function would look something like this:
func generateGrid() {
for i in 0..<5 {
// Every other line needs to be shifted
var offsetX = 0
if i % 2 == 0 {
offsetX = 0
} else {
offsetX = tile.size.width / 2.0
}
for j in 0..<5 {
var tile = Tile()
// Every other line needs to be shifted
var offsetY = 0
if i % 2 == 0 {
offsetX = 0
} else {
offsetX = tile.size.height / 2.0
}
tile.position = CGPoint(x: (i * tile.size.width) - offsetX, y: (j * tile.size.height) - offsetY)
addChild(tile)
}
}
}
source to share