我建议你将网格实现为SKSpriteNode
的纹理,因为Sprite Kit将在一次绘制调用中呈现网格。这里有一个如何做一个例子:
class Grid:SKSpriteNode {
var rows:Int!
var cols:Int!
var blockSize:CGFloat!
convenience init?(blockSize:CGFloat,rows:Int,cols:Int) {
guard let texture = Grid.gridTexture(blockSize: blockSize,rows: rows, cols:cols) else {
return nil
}
self.init(texture: texture, color:SKColor.clear, size: texture.size())
self.blockSize = blockSize
self.rows = rows
self.cols = cols
}
class func gridTexture(blockSize:CGFloat,rows:Int,cols:Int) -> SKTexture? {
// Add 1 to the height and width to ensure the borders are within the sprite
let size = CGSize(width: CGFloat(cols)*blockSize+1.0, height: CGFloat(rows)*blockSize+1.0)
UIGraphicsBeginImageContext(size)
guard let context = UIGraphicsGetCurrentContext() else {
return nil
}
let bezierPath = UIBezierPath()
let offset:CGFloat = 0.5
// Draw vertical lines
for i in 0...cols {
let x = CGFloat(i)*blockSize + offset
bezierPath.move(to: CGPoint(x: x, y: 0))
bezierPath.addLine(to: CGPoint(x: x, y: size.height))
}
// Draw horizontal lines
for i in 0...rows {
let y = CGFloat(i)*blockSize + offset
bezierPath.move(to: CGPoint(x: 0, y: y))
bezierPath.addLine(to: CGPoint(x: size.width, y: y))
}
SKColor.white.setStroke()
bezierPath.lineWidth = 1.0
bezierPath.stroke()
context.addPath(bezierPath.cgPath)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return SKTexture(image: image!)
}
func gridPosition(row:Int, col:Int) -> CGPoint {
let offset = blockSize/2.0 + 0.5
let x = CGFloat(col) * blockSize - (blockSize * CGFloat(cols))/2.0 + offset
let y = CGFloat(rows - row - 1) * blockSize - (blockSize * CGFloat(rows))/2.0 + offset
return CGPoint(x:x, y:y)
}
}
,这里是如何创建一个网格,游戏件添加到网格
class GameScene: SKScene {
override func didMove(to: SKView) {
if let grid = Grid(blockSize: 40.0, rows:5, cols:5) {
grid.position = CGPoint (x:frame.midX, y:frame.midY)
addChild(grid)
let gamePiece = SKSpriteNode(imageNamed: "Spaceship")
gamePiece.setScale(0.0625)
gamePiece.position = grid.gridPosition(row: 1, col: 0)
grid.addChild(gamePiece)
}
}
}
更新:
要确定哪些网格广场被感动,加入这个到init
self.isUserInteractionEnabled = true
和这个到Grid
类:
override func touchesBegan(_ touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let position = touch.location(in:self)
let node = atPoint(position)
if node != self {
let action = SKAction.rotate(by:CGFloat.pi*2, duration: 1)
node.run(action)
}
else {
let x = size.width/2 + position.x
let y = size.height/2 - position.y
let row = Int(floor(x/blockSize))
let col = Int(floor(y/blockSize))
print("\(row) \(col)")
}
}
}
为什么不使用CGContext(Quartz)来画线?看看CGPaths。唯一需要注意的是确保坐标共同引入。毕竟,精灵是精灵... – 2015-11-01 17:27:38
嘿,迈克尔L!感谢您的建议。我不知道如何以有效的方式使用这些CGPath,但0x141E的答案完美无缺。 – Alex
网格是否需要在屏幕上显示,因为您应该将屏幕的长度分成所需的网格长度。 – Cing