Более высокий индекс столбца и строки, чем количество столбцов и строк в SKTileMapNode

Я хочу создать сцену, в которой у меня есть кнопки для перемещения курсора от плитки к плитке внутри SKTileMapNode. Я создал SKTileMapNode 10x8 во внешнем файле .sks в редакторе сцен Spritekit. Чтобы установить положение курсора точно так же, как плитка, я хотел зарегистрировать конкретный индекс столбца и строки плитки, а затем узнать его позицию. Использование функций numberOfColumns и tileRowIndex дает мне более высокие значения, чем numberOfRows и tileRowIndex, которые равны 10 и 8. В результате этой проблемы мой курсор отображается в неправильном положении. Он даже не выровнен по какой-либо позиции плитки.

class Spielfeld: SKScene {

    var x: Int = 0     // Anzahl Felder in x-Richtung
    var y: Int = 0     // Anzahl Felder in y-Richtung
    var tilemap: SKTileMapNode = SKTileMapNode()
    var up: SKSpriteNode = SKSpriteNode()
    var down: SKSpriteNode = SKSpriteNode()
    var left: SKSpriteNode = SKSpriteNode()
    var right: SKSpriteNode = SKSpriteNode()
    var cursor: SKSpriteNode = SKSpriteNode(imageNamed: "Cursor1Blue")

    override func sceneDidLoad() {
        up = self.childNode(withName: "Up") as! SKSpriteNode
        down = self.childNode(withName: "Down") as! SKSpriteNode
        left = self.childNode(withName: "Left") as! SKSpriteNode
        right = self.childNode(withName: "Right") as! SKSpriteNode

        tilemap = self.childNode(withName: "Tile Map Node") as! SKTileMapNode
        cursor.position = tilemap.centerOfTile(atColumn: 5, row: 5)
        cursor.zPosition = 0.1
        self.addChild(cursor)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch:UITouch = touches.first! as UITouch
        let positionInScene = touch.location(in: self)
        let touchedNode = self.atPoint(positionInScene)
        print(touchedNode.name!)
        if(touchedNode.name == "Tile Map Node") {
            let map = touchedNode as! (SKTileMapNode)
            print(map.tileColumnIndex(fromPosition: positionInScene))   // higher than 10
            print(map.tileRowIndex(fromPosition: positionInScene))      // higher than 8
            print(map.numberOfColumns)  // 10
            print(map.numberOfRows)     // 8
            print(map)
        }
    }
}

person T. Yueksel    schedule 16.03.2019    source источник


Ответы (1)


При получении индекса с помощью tileColumnIndex/tileRowIndex вам необходимо свериться с положением на карте тайлов. В вашем примере вы указываете позицию для сцены, которая может быть разной, в зависимости от того, где расположена карта плитки.

Если вы используете затронутое местоположение на карте, вы должны получить правильные индексы.

let positionInMap = touch.location(in: map)
let column = map.tileColumnIndex(fromPosition: positionInMap)
let row = map.tileRowIndex(fromPosition: positionInMap)

Обновленная версия touchesBegan() из вашего примера

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    let touch:UITouch = touches.first! as UITouch
    let positionInScene = touch.location(in: self)
    let touchedNode = self.atPoint(positionInScene)
    if(touchedNode.name == "Tile Map Node") {
        let map = touchedNode as! (SKTileMapNode)
        let positionInMap = touch.location(in: map) // Get the touched position in map
        print(map.tileColumnIndex(fromPosition: positionInMap))
        print(map.tileRowIndex(fromPosition: positionInMap))
        print(map.numberOfColumns)
        print(map.numberOfRows)
        print(map)
    }
}

Чтобы убедиться, что ваш курсор выровнен с тайлами при использовании centerOfTile для его позиционирования, добавьте его в качестве дочернего элемента на карту тайлов, чтобы убедиться, что они находятся в одной системе координат. В противном случае вам придется добавить необходимые смещения к позиции курсора.

tilemap.addChild(cursor)
person Johan Steen    schedule 17.03.2019