Andy
Andy

Reputation: 137

Sprite Kit game design for chess game

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.

Upvotes: 2

Views: 543

Answers (2)

Yaming Lin
Yaming Lin

Reputation: 123

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

Upvotes: 1

Maury Markowitz
Maury Markowitz

Reputation: 9273

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".

Upvotes: 1

Related Questions