I want to create a scene where I have buttons to move a cursor from tile to tile inside a SKTileMapNode. I created a 10x8 SKTileMapNode in an extern .sks file in the Spritekit Scene Editor. To set the cursors position exactly on the same as a tile, i wanted to register the specific column and row index of the tile and then find out his position. Using the functions numberOfColumns and tileRowIndex give me higher values than numberOfRows and tileRowIndex, which are 10 and 8. As a result of this Problem my cursor is being displayed on a wrong position. It isn't even even aligned on any tiles position.
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)
}
}
}
When getting the index with
tileColumnIndex/tileRowIndexyou need to check against the position within the tile map. In your example you give the position for the scene, which might not be the same, depending on where the tile map is positioned.If you use the touched location in the map, you should get the correct indexes returned.
An updated version of
touchesBegan()from your exampleTo ensure that your cursor gets aligned with the tiles when using
centerOfTileto position it, add it as a child to the tile map to ensure they are on the same coordinate system. Else you'll have to add the necessary offsets to the cursor position.