Dibuja una cuadrícula con SpriteKit

¿Cuál sería la mejor manera de dibujar una cuadrícula como esta usando el motor de juego SpriteKit 2D? Requisitos:

  • Ingrese programáticamente el número de columnas y filas (5×5, 10×3, 3×4, etc.).
  • SKSpriteNode mediante progtwigción usando algo como SKSpriteNode o SKShapeNode , ya que solo el uso de imágenes de un cuadrado como este no me parece muy eficiente.
  • Los cuadrados deben tener un tamaño fijo (digamos que cada uno es 40×40).
  • La cuadrícula debe estar cinput vertical y horizontalmente en la vista.

Estoy planeando usar un SKSpriteNode (de una image) como un jugador que se mueve en diferentes cuadrados en esta cuadrícula.
Por lo tanto, voy a save en una matriz de 2 dimensiones el punto central (x, y) de cada cuadrado y luego pasar de la position actual del jugador a esa position. Si tienes una mejor sugerencia para esto también, me gustaría escucharlo.

Agradecería una solución en Swift (preferiblemente 2.1), pero Objective-C también lo haría. Planeando usar esto solo en dispositivos iPhone.
Mi pregunta es cercana a esta . Cualquier ayuda es apreciada.

Te sugiero que implemente la cuadrícula como una textura de un SKSpriteNode porque Sprite Kit renderizará la cuadrícula en una sola llamada. Aquí hay un ejemplo de cómo hacerlo:

 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) } } 

Y aquí está cómo crear una cuadrícula y agregar una pieza del juego a la cuadrícula.

 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) } } } 

Actualizar:

Para determinar qué cuadrado de la cuadrícula se tocó, agregue esto a init

 self.isUserInteractionEnabled = true 

y esto a la class 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)") } } }