使用SpriteKit绘制网格

使用SpriteKit 2D游戏引擎绘制这样的网格最好的方法是什么? 要求:

  • 以编程方式输入列数和行数(5×5,10×3,3×4等)。
  • 使用像SKSpriteNodeSKShapeNode这样的程序编程来绘制它,因为只使用这样的正方形图像对我来说似乎不是很有效。
  • 正方形应该有一个固定的大小(假设每个都是40×40)。
  • 网格应在视图中垂直和水平居中。

我打算使用SKSpriteNode (来自图像)作为在此网格中移动不同方块的玩家。
因此,我将在二维数组中保存每个方块的中心点(x,y),然后从玩家的当前位置移动到该位置。 如果您对此也有更好的建议,我想听听。

我很欣赏Swift中的解决方案(最好是2.1),但Objective-C也会这样做。 计划仅在iPhone设备上使用它。
我的问题接近这一点 。 任何帮助表示赞赏。

我建议您将网格实现为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, 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)") } } }