如何在SpriteKit中将对象放在不同的Z层上

时间:2017-03-22 18:09:40

标签: swift sprite-kit sknode

在我的游戏中,我试图将图像放在不同的图层上,这样就可以清楚地了解事物的位置。

E.g。地形位于Z层0,而改进和城市位于Z层1,而单位位于更高层。

我正在关注一个教程(http://helpmecodeswift.com/sprite-kit/spritekit-gameift-2-0-part-2)并且正在复制他们的方法(更改名称以满足我的需要)并且它似乎不起作用。

以下是来自完全相同代码的两张图片(我想要一张右边的图片,虽然红色城市也应该有一个单位):

Units under cities

Blue unit above city, Red unit still under city

问题(不是话题问题):为什么这些图像无法加载?

注意:大方块的颜色是" cities&#34 ;,而棋子看起来是单位,图形只是填充,直到我完成大部分游戏并实际制作专用纹理。

以下是处理图层的代码(单位和城市放在正确的图层上):

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!

1 个答案:

答案 0 :(得分:2)

这就是我的做法

gameLayer是在SKS文件中设置的,这就是为什么它的初始化方式与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)
    }
}