1

I've been working this for days. I have created a tile map in the level editor. It loads in my code fine but when I iterate over the tiles, none of them show as having a definition. Not sure what I'm doing wrong.

Everything runs fine but it won't load the tile definitions.

SKTileNode

Tileset Level

'import SpriteKit

protocol EventListenerNode {
    func didMoveToScene()
}

typealias TileCoordinates = (column: Int, row: Int)

class GameScene: SKScene {

    var car = CarNode()
    var holdingAcceleration = false
    var mainCamera = SKCameraNode()
    var hub = SKNode()
    var levelHolder: SKNode!

    override func didMove(to view: SKView) {
        levelHolder = childNode(withName: "levelHolder")

        struct PhysicsCategory {
            static let None:  UInt32 = 0
            static let CarBody:   UInt32 = 0b1 // 0001 or 1
            static let Ground: UInt32 = 0b10 // 0010 or 2
            static let Tires:   UInt32 = 0b100 // 0100 or 4
        }

        // This code sends a message to all nodes added to scene that conform to the EventListenerNode protocol
        enumerateChildNodes(withName: "//*", using: { node, _ in
            if let eventListenerNode = node as? EventListenerNode {
                eventListenerNode.didMoveToScene()
                //print("calling to all nodes.  didMoveToScene")
            }
        })

        car = childNode(withName: "//Car") as! CarNode
        mainCamera = childNode(withName: "//Camera") as! SKCameraNode
        camera = mainCamera

//        /* Load Level 1 */
        let resourcePath = Bundle.main.path(forResource: "TestLevel", ofType: "sks")
        let level = SKReferenceNode (url: URL (fileURLWithPath: resourcePath!))
        levelHolder.addChild(level)
        let levelTileNode = childNode(withName: "//levelTileNode") as! SKTileMapNode
        var splinePoints = createGroundWith(tileNode:levelTileNode)

        let ground = SKShapeNode(splinePoints: &splinePoints,
                                 count: splinePoints.count)
        ground.lineWidth = 5
        ground.physicsBody = SKPhysicsBody(edgeChainFrom: ground.path!)
        ground.physicsBody?.restitution = 0.75
        ground.physicsBody?.isDynamic = false

        // Add the two nodes to the scene
        scene?.addChild(ground)

        ////////////////////////////Test///////////////////

    }

    override func update(_ currentTime: TimeInterval) {
        if holdingAcceleration{
            car.accelerate()
        }
        let carPosition = car.scene?.convert(car.position, from: car.parent!)

        mainCamera.position = carPosition!

    }


    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches{
            let location = touch.location(in: self)
            let touchNode = atPoint(location)

            if touchNode.name == "Gas"{
                holdingAcceleration = true
            }
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches{
            let location = touch.location(in: self)
            let touchNode = atPoint(location)

            if touchNode.name == "Gas"{
                holdingAcceleration = false
            }
        }
    }

    /*
    func createSplineFrom(tileNode: SKTileMapNode)->[CGPoint]{
        print("entered the createSpline function")
        var arrayOfPoints = [CGPoint]()
        let tileMap = tileNode

        let tileSize = tileMap.tileSize
        let halfWidth = CGFloat(tileMap.numberOfColumns) / 2.0 * tileSize.width
        let halfHeight = CGFloat(tileMap.numberOfRows) / 2.0 * tileSize.height

        for col in 0..<tileMap.numberOfColumns {
            print("in column \(col) of \(tileMap.numberOfColumns)")

            for row in 0..<tileMap.numberOfRows {
                //print("col: \(col) row: \(row)")

                if let tileDefinition = tileMap.tileDefinition(atColumn: col, row: row)
                {
                    print("tileDefinition is found.  Holy cow")

                    let isEdgeTile = tileDefinition.userData?["groundFriction"] as? Int  //uncomment this if needed, see article notes
                    if (isEdgeTile != 0) {
                        let tileArray = tileDefinition.textures
                        //let tileTexture = tileArray[0]
                        let x = CGFloat(col) * tileSize.width - halfWidth + (tileSize.width/2)
                        let y = CGFloat(row) * tileSize.height - halfHeight + (tileSize.height/2)
                        _ = CGRect(x: 0, y: 0, width: tileSize.width, height: tileSize.height)
                        arrayOfPoints.append(CGPoint(x: x, y: y))

                        //let tileNode = SKNode()

                        //tileNode.position = CGPoint(x: x, y: y)

                    }
                }

            }
        }

        print(arrayOfPoints.count)

        return arrayOfPoints
    }
    */

    func tile(in tileMap: SKTileMapNode, at coordinates: TileCoordinates) -> SKTileDefinition? {
            return tileMap.tileDefinition(atColumn: coordinates.column,    row: coordinates.row)
    }

    func createGroundWith(tileNode:SKTileMapNode) -> [CGPoint] {
        var arrayOfPoints = [CGPoint]()
        print("inside createGround")
        let groundMap = tileNode

        let tileSize = groundMap.tileSize
        let halfWidth = CGFloat(groundMap.numberOfColumns) / 2.0 * tileSize.width
        let halfHeight = CGFloat(groundMap.numberOfRows) / 2.0 * tileSize.height

        for row in 0..<groundMap.numberOfRows {
            for column in 0..<groundMap.numberOfColumns {
                // 2
                guard let tileDefinition = tile(in: groundMap, at: (column, row))
                    else { continue }
                print("inside tileDefinitioin")
                let isEdgeTile = tileDefinition.userData?["groundFriction"] as? Int
                if (isEdgeTile != 0) {
                    let tileArray = tileDefinition.textures
                    //let tileTexture = tileArray[0]
                    let x = CGFloat(column) * tileSize.width - halfWidth + (tileSize.width/2)
                    let y = CGFloat(row) * tileSize.height - halfHeight + (tileSize.height/2)
                    _ = CGRect(x: 0, y: 0, width: tileSize.width, height: tileSize.height)
                    arrayOfPoints.append(CGPoint(x: x, y: y))
                }
        // 4
        //bugsNode.name = "Bugs"
        //addChild(bugsNode)
        // 5
        //bugsMap.removeFromParent()
            }

        }
        return arrayOfPoints
    }
}

`

Knight0fDragon
  • 16,609
  • 2
  • 23
  • 44
  • Thanks for the edit but why the downvote? I've researched for days on why tileMap.definition is not returning something. I've tried loading the scene directly in the gamescene with no change in result. I've added extra tiles to cover every square to see if maybe a certain tile was having issues. I'm just not sure where to go on this question. I've looked at all of Apple's documentation on this and nothing. – Metalboyblue Sep 22 '17 at 13:27
  • Don't know why somebody downvoted, I only gave you more tags to help your results out – Knight0fDragon Sep 22 '17 at 13:54

1 Answers1

2

So I figured it out. The tileset had an "OnDemand" resource tag. Since I didn't realize that, the game wasn't loading the tiles automatically from the game scene. Always something simple.