为了尝试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列,或者可能是距离我点击的一些瓷砖的瓷砖。
另外,我无法禁用调整窗口大小的功能。
任何帮助都会很棒,所以提前谢谢你。
答案 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)