kev3kev3
kev3kev3

Reputation: 197

Swift creating a class to draw a tile map and adding the map to a game scene

I have created a class in which at the moment I am attempting to create a tile map made up of 36 coloured squares which are SKSpriteNodes. I am getting a run time error and I think the problem is due to the SKSpriteNodes not being correctly added to an SKNode. I am new to SpriteKit and attempting to write this in Swift.

Below is my map class (I know it is not Isometric currently) and the GameScene class in which I am trying to use it.

Can anyone explain where I am going wrong, also any general comments on whether I am doing things in a particularly poor way would be appreciated.

class IsometricMap {

let map = SKNode()
let mapLayout = Array<Array<Int>>()
let numColumns: Int
let numRows: Int
let tileHeight: Int
let tileWidth:Int
let grassNode: SKSpriteNode
let wallNode: SKSpriteNode

init(mapLayout: Array<Array<Int>>,numColumns: Int, numRows: Int, tileHeight: Int, tileWidth: Int) {
    self.mapLayout = mapLayout
    self.numColumns = numColumns
    self.numRows = numRows
    self.tileHeight = tileHeight
    self.tileWidth = tileWidth
    self.grassNode = SKSpriteNode(color: UIColor.greenColor(), size: CGSizeMake(CGFloat(tileHeight), CGFloat(tileWidth)))
    self.wallNode = SKSpriteNode(color: UIColor.brownColor(), size: CGSizeMake(CGFloat(tileHeight), CGFloat(tileWidth)))
}

func drawMap() {
    var tileType: Int
    var columnCount = 0
    var rowCount = 0
    for column in mapLayout {
        for row in column {
            var xPos = columnCount * tileWidth
            var yPos = rowCount * tileHeight
            tileType = mapLayout[columnCount][rowCount]
            placeTile(tileType, xPos: CGFloat(xPos), yPos: CGFloat(yPos))
            ++rowCount
        }
        ++columnCount
    }
}

func placeTile(tileType: Int, xPos: CGFloat, yPos: CGFloat) {
    switch tileType{
    case 0:
        grassNode.position = CGPointMake(xPos, yPos)
        map.addChild(grassNode)
    case 1:
        wallNode.position = CGPointMake(xPos, yPos)
        map.addChild(wallNode)
    default:self
        println("Out of range error")
    }
}

}

class GameScene: SKScene {

let simpleMap = [[1, 1, 1, 1, 1, 1],
    [1, 0, 0, 0, 0, 1],
    [1, 0, 0, 0, 0, 1],
    [1, 0, 0, 0, 0, 1],
    [1, 0, 0, 0, 0, 1],
    [1, 1, 1, 1, 1, 1]]

override func didMoveToView(view: SKView) {
    /* Setup your scene here */
    let myLabel = SKLabelNode(fontNamed:"Chalkduster")
    myLabel.text = "Hello, World!";
    myLabel.fontSize = 65;
    myLabel.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame));

    let starterMap = IsometricMap(mapLayout: simpleMap, numColumns: 6, numRows: 6, tileHeight: 50, tileWidth: 50)
    starterMap.drawMap()
    self.addChild(starterMap.map)

    //self.addChild(myLabel)
}

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    /* Called when a touch begins */
}

override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */
}

}

Upvotes: 4

Views: 2468

Answers (1)

Pieter
Pieter

Reputation: 17715

As far as I can tell, you are constantly changing the position of grassNode and wallNode and then re-adding it to the map node. If I understand your intentions correctly you want to recreate a grass- or wallnode for every placeTile and add that (newly created) node each time.

I would also inherit IsometricMap from SKNode, I see no need for the extra map variable.
Expecting the user of the class to call drawMap to get the class in a consistent state feels weird too, but there's not enough context to suggest what would be the best alternative (my first idea would be to put that functionality in the init method)

Upvotes: 2

Related Questions