2

In my game I am trying to put images on different layers so that it is clear where things are.

E.g. Terrain is at Z layer 0, while improvements and cities are at Z layer 1, while units are at a higher layer.

I am following a tutorial (http://helpmecodeswift.com/sprite-kit/spritekit-gameift-2-0-part-2) and am copying their method (changing the names to fit my needs) and it does not seem to work.

Here are two images from the exact same code (I want the one on the right, although the red city should have a unit on top of it too):

Units under cities

Blue unit above city, Red unit still under city

Question (not topic question): Why won't these images load?

Note: The large squares of color are "cities", while the checker looking pieces are units, the graphics are just filler until I finish off most of the game and actually make dedicated textures.

Here is the code that deals with the layers (units and cities are being put on the right layers):

class GameScene: SKScene {

    var mapTerrain: SKTileMapNode!

    override func sceneDidLoad() {
        cam = SKCameraNode()
        cam.xScale = 1
        cam.yScale = 1
        self.camera = cam
        self.addChild(cam)
        cam.position = CGPoint(x: 100, y: 100)
        setUpLayers()
        loadSceneNodes()
        setUpUI()
        testSpawn()
        //print("\(self.frame.width), \(self.frame.height)")
    }

    func setUpUI(){
        zoomIn.setButtonType(NSMomentaryLightButton)
        zoomIn.title = "Zoom In"
        zoomIn.alternateTitle = "Zoom In"
        zoomIn.acceptsTouchEvents = true
        view?.addSubview(zoomIn) //put button on screen

        zoomOut.setButtonType(NSMomentaryLightButton)
        zoomOut.title = "Zoom Out"
        zoomOut.alternateTitle = "Zoom Out"
        zoomOut.acceptsTouchEvents = true
        view?.addSubview(zoomOut) //put button on screen

        endTurn.setButtonType(NSMomentaryLightButton)
        endTurn.title = "End Turn"
        endTurn.alternateTitle = "End Turn"
        endTurn.acceptsTouchEvents = true
        view?.addSubview(endTurn) //put button on screen

    }

    func loadSceneNodes(){
        guard let mapTerrain = childNode(withName: "mapTerrain")
            as? SKTileMapNode else{
            fatalError("Background node not loaded")
        }
        self.mapTerrain = mapTerrain
        //GKGridGraph
    }

    func setUpLayers() {
        improvementsLayer = SKNode()
        improvementsLayer.name = "Objects Layer"
        addChild(improvementsLayer)
        unitsLayer = SKNode()
        unitsLayer.name = "Units Layer"
        addChild(unitsLayer)
    }

    func testSpawn(){
        if spawnCount == 0{
            for i in 0...10{
                spawnRedLegion(at: mapTerrain.centerOfTile(atColumn: 2, row: i), i: i)
            }
            for i in 0...10{
                spawnBlueLegion(at: mapTerrain.centerOfTile(atColumn: 3, row: i), i: i)
            }
            spawnCount += 1
            for i in 0...0{
                spawnRedCity(at: mapTerrain.centerOfTile(atColumn: 0, row: 1), i: i)
                spawnBlueCity(at: mapTerrain.centerOfTile(atColumn: 5, row: 1), i: i) 
            }
        }
    }

    func spawnRedLegion(at: CGPoint, i: Int){
        let RedLegion = legion(texture: textureRedLegion, moveTo: nil, tag: i, health: 2)
        RedLegion.position = at
        RedLegion.team = "Red"
        unitsLayer.addChild(RedLegion)
        legionList.append(RedLegion)
    }

    func spawnBlueLegion(at: CGPoint, i: Int){
        let BlueLegion = legion(texture: textureBlueLegion, moveTo: nil, tag: i, health: 2)
        BlueLegion.position = at
        BlueLegion.team = "Blue"
        unitsLayer.addChild(BlueLegion)
        legionList.append(BlueLegion)
    }

    func spawnRedCity(at: CGPoint, i: Int){
        let RedCity = city(texture: textureRedCity, tag: i, health: 1, production: 1, workDone: 0)
        RedCity.position = at
        RedCity.team = "Red"
        improvementsLayer.addChild(RedCity)
        cityList.append(RedCity)
    }

    func spawnBlueCity(at: CGPoint, i: Int){
        let BlueCity = city(texture: textureBlueCity, tag: i, health: 1, production: 1, workDone: 0)
        BlueCity.position = at
        BlueCity.team = "Blue"
        improvementsLayer.addChild(BlueCity)
        cityList.append(BlueCity)
    }
    ....
}

//this is in another file

let textureRedLegion = SKTexture(imageNamed: "Red Checker")
let textureBlueLegion = SKTexture(imageNamed: "Black Checker")
let textureRedCity = SKTexture(imageNamed: "Red Square")
let textureBlueCity = SKTexture(imageNamed: "Black Square")

struct layers {

    static let background: CGFloat = 0
    static let improvements: CGFloat = 1
    static let units: CGFloat = 3

}

var improvementsLayer: SKNode!
var unitsLayer: SKNode!
Student-LTB
  • 103
  • 8
  • you're not showing any code where you actually set the zPosition of the objects – Ron Myschuk Mar 22 '17 at 18:14
  • They are added to the layers I created. E.g. 'improvementsLayer.addChild(BlueCity)' – Student-LTB Mar 22 '17 at 18:16
  • yes, but you are not showing the code. You are asking a question specifically about zPosition layering yet you don't show the relevant code to what you are already trying – Ron Myschuk Mar 22 '17 at 18:19
  • I am looking at the tutorial and it seems like the struct should be setting up the z-layers. Is it possible I am doing that wrong? Do you have an alternative way to put the objects on different Z-layers? (I will add in spawn code). – Student-LTB Mar 22 '17 at 18:24

1 Answers1

2

this is how I do it

The gameLayer is setup in an SKS file that is why it is initialized differently than the controlsLayer

enum Layer: CGFloat {
    case background = 0
    case gameLayer = 20
    case controls = 100
}

class GameScene: SKScene, SKPhysicsContactDelegate {

    private var gameLayer = SKNode()
    private var controlsLayer = SKNode()

    override func didMove(to view: SKView) {

        if let gameLayer = self.childNode(withName: "gameLayer") {
            self.gameLayer = gameLayer
            self.gameLayer.zPosition = Layer.gameLayer.rawValue
        }

        controlsLayer.zPosition = Layer.controls.rawValue
        addChild(controlsLayer)

        setupObjects()
    }

    func setupObjects() {

        let pauseButton = SKSpriteNode(texture: nil, color: .red, size: CGSize(width: 100, height: 100)
        pauseButton.position = CGPoint(x: 100, y: 100)
        controlsLayer.addChild(pauseButton)

        //OR USE IT THIS WAY

        let ball = SKSpriteNode(texture: nil, color: .red, size: CGSize(width: 100, height: 100)
        ball.position = CGPoint(x: 400, y: 400)
        ball.zPosition = Layer.gameLayer.rawValue
        self.addChild(ball)
    }
}
Ron Myschuk
  • 6,011
  • 2
  • 20
  • 32
  • Your comment gave me the idea to add 'improvementsLayer.zPosition = layers.improvements' and 'unitsLayer.zPosition = layers.units' to the code. – Student-LTB Mar 22 '17 at 18:47