2
votes

I am new to Swift and iOS, I am planning to design a chess game (chinese chess) in iOS using Sprite Kit. I've been brainstorming the design strategies. I have a question regarding creating the chess board and how the pieces move.

Unlike chess, each piece move to an intersection point, I am seeing people who make chess game board by creating each tile as a separate UIview, since the chinese chess board is harder to draw I was planning to just use the board image as one node, and each pieces simply move on top of the board. left right up down by calculating the distance of each square. ( for example, dividing the board width by 8 since there are 8 equal squares a row) Is this a good strategy or is there a better way of implementing. I find this way not the most efficient since if the device changes, the board and pieces size would stay the same?

enter image description here

I would appreciate it if anyone can give me some advice.

2
If you want to use board image, how you going to move the pieces? - canister_exister
each piece would be a node as well, I'll move them by using SKAction horizontal or vertical by find the x and y value. - Andy
You could set scaleMode to .resizeFill to have the board size stay the same. - Yaming Lin
Look into gameplaykit. You can institute path finding, which sets up how your sprite can move from each cell location - Knight0fDragon

2 Answers

1
votes

I did precisely this sort of thing for a port of the classic game "Chase!". In my case the background graphic was not static, as the board layout could be changed by the user if desired.

Basically all I did was use the UIView bounds and found the smallest dimension, which is the narrow direction of the screen. I then scaled the grid to that size and placed it in the middle of the UIView.

Since the number of tiles in your case is fixed, it is easy to calculate a grid location for a given screen location and vice versa.

So to answer you more directly, "yes, that is the way to do it".

1
votes

Here is a tutorial using the similar grid. https://www.raywenderlich.com/55-how-to-make-a-game-like-candy-crush-with-spritekit-and-swift-part-1

First, you should create a helper class Array<2D> for your tiles and chess.

struct Array2D<T> {
  let columns: Int
  let rows: Int
  private var array: Array<T?>

  init(columns: Int, rows: Int) {
    self.columns = columns
    self.rows = rows
    array = Array<T?>(repeating: nil, count: rows*columns)
  }

  subscript(column: Int, row: Int) -> T? {
    get {
      return array[row*columns + column]
    }
    set {
      array[row*columns + column] = newValue
    }
  }
}

You can create a custom class Chess, like this

import SpriteKit

// MARK: - ChessType
enum ChessType: Int {
  case unknown = 0, Horse, King, etc. 
}

// MARK: - Chess
class Chess: CustomStringConvertible, Hashable {

  func hash(into hasher: inout Hasher) {
    hasher.combine(row)
    hasher.combine(column)
  }

  static func ==(lhs: Cookie, rhs: Cookie) -> Bool {
    return lhs.column == rhs.column && lhs.row == rhs.row

  }

  var description: String {
    return "type:\(chessType) square:(\(column),\(row))"
  }

  var column: Int
  var row: Int
  let chessType: ChessType
  var sprite: SKSpriteNode?

  init(column: Int, row: Int, chessType: ChessType) {
    self.column = column
    self.row = row
    self.chessType = chessType
  }
}

To find a particular point/tile, you can use these helper methods in your game scene:

  private func pointFor(column: Int, row: Int) -> CGPoint {
    return CGPoint(x: CGFloat(column) * tileWidth + tileWidth/2,
                   y: CGFloat(row) * tileHeight + tileHeight/2)
  }

  private func convertPoint(_ point: CGPoint) -> (success: Bool, column: Int, row: Int) {
    if point.x >= 0 && point.x < CGFloat(numColumns) * tileWidth {
      if point.y >= 0 && point.y < CGFloat(numRows) * tileHeight {
        return (true, Int(point.x/tileWidth), Int(point.y/tileHeight))
      }
    }
    return (false, 0, 0)
  }