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.

+3


source to share


2 answers


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)
}

      

Isometric grid with buildings

Figure 1. Isometric grid created using the above code

+8


source


To create such an isometric grid

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)
        }
    }
}

      

+7


source







All Articles