The only reason I'm attempting this programmatically is so I can access the locations of each tile, making it possible to manipulate the grid. I've looked at about 15 different tutorials using other programming languages, but even with that knowledge, I'm still having a very difficult time creating one in Swift.
I've tried creating a nested for loop but I'm not even sure if the code inside the loops make logical sense for creating an isometric grid, I just took it off of 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 can't add the same node more than once.
Please give me any direction that you can.
Here's an example of how to create an isometric grid in SpriteKit:
Define the grid settings
let tileHeight:CGFloat = 16.0
let tileWidth:CGFloat = 32.0
let numRows = 5
let numCols = 6
Create grid elements 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 a grid position to x and y scene coordinates. Use this to create the grid and to add buildings on 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-shaped SKShapeNode
func newTile(size:CGSize) -> SKShapeNode {
let shape = SKShapeNode()
let path = UIBezierPath()
path.move(to: CGPoint(x:0, y:size.height / 2.0))
path.addLine(to: CGPoint(x:size.width / 2.0, y:0))
path.addLine(to: CGPoint(x:0, y:-size.height / 2.0))
path.addLine(to: CGPoint(x:-size.width / 2.0, y:0))
path.close()
shape.path = path.cgPath
shape.lineWidth = 1.0
shape.fillColor = SKColor.gray
return shape
}
This function determines the appropriate z position to ensure that buildings placed on the grid will be rendered in the correct order.
func buildingZPosition(col:Int, row:Int) -> CGFloat {
return CGFloat(row*numCols + numCols-col)
}
Figure 1. Isometric Grid Created with the Above Code
To create an isometric grid like so
one has to create a two loops. One of them iterates through rows and the other iterates through columns. Notice that the center of every other column is shifted up by half of the height of the tile and the same for every other row. To compensate for this we check if the row and column is even or odd and adjust it 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)
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With