Reputation: 137
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?
I would appreciate it if anyone can give me some advice.
Upvotes: 2
Views: 543
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
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