单击时将SKSpriteNode放入矩阵中

时间:2014-10-26 11:02:04

标签: macos swift sprite-kit

为了尝试SpriteKit和Swift for OS X(不适用于iOS),我想创建一个Minesweeper游戏。

游戏背后的所有逻辑已经完成(并证明它有效,我做的是大学项目,但是使用CLI界面),但我遇到的主要问题是UI。

我有一个10x10平铺矩阵,在用户点击屏幕后我无法获得正确的平铺。

我的代码如下所示:

class Tile {
    var sprite: SKSpriteNode
    var isBomb: Bool
    var isUnlocked: Bool
    var row: Int
    var col: Int

    init(sprite: SKSpriteNode, row: Int, col: Int){
        // Default assignations
        self.sprite.name = "\(row):\(col)"
    }

}

class GameScene: SKScene {


    var board: [[Tile]] = [[Tile]]()
    let ROWS: Int = 10
    let COLS: Int = 10

    override func didMoveToView(view: SKView){

        for row in 0..<ROWS {
            board.append([Tile]())
            for col in 0..<COLS{
                var tileSprite = SKSpriteNode(imageNamed: "tile")

                var x: CGFloat = (tileSprite.size.height * CGFloat(row))+(tileSprite.size.height/2)
                var y: CGFloat = (tileSprite.size.width * CGFloat(col))+(tileSprite.size.width/2)

                tileSprite.position = CGPoint(x: x, y: y)

                // I also add it here, just for ensuring that the name is set
                tileSprite.name = "\(row):\(col)"

                board[row].append(Tile(sprite: tileSprite, row: row, col: col))
                addChild(tileSprite)
            }
        }

    }

    func getRowColFromNode(node: SKSpriteNode) -> (row: Int, col: Int){

        var row: Int = 0
        var col: Int = 0

        /*var xPosition = node.position.x
        var yPosition = node.position.y

        row = Int(yPosition/node.size.height)
        col = Int(xPosition/node.size.width)*/

        if let name = node.name {

            println("NAME: \(name)")

            var rowString: String
            var colString: String

            var nameSplit = name.componentsSeparatedByString(":")

            rowString = nameSplit[0]
            colString = nameSplit[1]

            row = rowString.toInt()!
            col = colString.toInt()!


            println("DETECTEDROW: \(row)")
            println("DETECTEDCOL: \(col)")

        }


        return (row, col)
    }

    override func mouseDown(theEvent: NSEvent) {

        var touchedNode: SKSpriteNode = nodeAtPoint(theEvent.locationInWindow) as SKSpriteNode

        var row: Int
        var col: Int


        (row, col) = getRowColFromNode(touchedNode)

        println("ROW: \(row)")
        println("COL: \(col)") 

    }

}

我甚至试过将theEvent.locationInWindow.y / tile.sprite.size.width分开,但我永远无法获得正确的图块。

有时我会得到第12行或第15列,或者可能是距离我点击的一些瓷砖的瓷砖。

另外,我无法禁用调整窗口大小的功能。

任何帮助都会很棒,所以提前谢谢你。

2 个答案:

答案 0 :(得分:1)

我建议你稍微重新考虑一下你的结构。为什么不将你的tile作为SKSpriteNode的子类(而不是包含一个)?

class TileSprite: SKSpriteNode {
    var isBomb: Bool // Perhaps use an enum for type instead as well?
    var isUnlocked: Bool
    var row: Int
    var col: Int

    init(row: Int, col: Int){
        // Default assignations
    }
}

然后在你的设置中:

for row in 0..<ROWS {
        board.append([Tile]())
        for col in 0..<COLS{
            var tileSprite = TileSprite(imageNamed: "tile")
            var x: CGFloat = (tileSprite.size.height * CGFloat(row))+(tileSprite.size.height/2)
            var y: CGFloat = (tileSprite.size.width * CGFloat(col))+(tileSprite.size.width/2)

            tileSprite.position = CGPoint(x: x, y: y)
            tileSprite.row = row
            tileSprite.col = col

            addChild(tileSprite)
        }
    }

和......

override func mouseDown(theEvent: NSEvent) {
        let touchedNode = nodeAtPoint(theEvent.locationInWindow) as TileSprite
        let row = touchedNode.row
        let col = touchedNode.col

        println("ROW: \(row)")
        println("COL: \(col)") 
    }

你也可以扩展这个以使row / col作为TileSprite的元组属性通过setter方法改变。然后,这个setter方法可以负责计算精灵的位置,清理场景设置。

答案 1 :(得分:1)

问题是鼠标点击的位置在视图的坐标系中。您需要将它们转换为场景坐标以选择正确的节点。这是一个如何做到这一点的例子......

override func mouseDown(theEvent: NSEvent) {
    // Convert the mouse-down event's location to scene coordinates
    let location = theEvent.locationInNode(self)
    let touchedNode = nodeAtPoint(location)