我是Swift和iOS的新手,我打算使用Sprite Kit在iOS中设计国际象棋游戏(中国象棋)。我一直在集体讨论设计策略。 我有一个关于创建棋盘以及棋子如何移动的问题。
与国际象棋不同,每块棋子都移动到交叉点,我看到有人通过将每个图块创建为单独的UIview来制作国际象棋游戏板,因为中国象棋棋盘较难绘制,我打算只使用棋盘图像作为一个节点,每个部件都可以在电路板上移动。通过计算每个正方形的距离从左到右向下。 (例如,由于连续有8个相等的正方形,因此将板宽除以8)这是个好策略还是有更好的实现方法?我发现这种方法不是最有效的方法,因为如果设备发生变化,电路板和部件的尺寸将保持不变?
如果有人能给我一些建议,我将不胜感激。
答案 0 :(得分:1)
我正是为经典游戏“ Chase!”的移植做了这种事情。在我的情况下,背景图形不是一成不变的,因为用户可以根据需要更改电路板布局。
基本上,我所做的只是使用UIView边界,并找到了最小的尺寸,即屏幕的狭窄方向。然后,我将网格缩放到该大小并将其放置在UIView的中间。
由于案例中的图块数量是固定的,因此可以轻松计算给定屏幕位置的网格位置,反之亦然。
因此,要直接回答您,“是的,这就是这样做的方法。”
答案 1 :(得分:1)
这里是使用类似网格的教程。 https://www.raywenderlich.com/55-how-to-make-a-game-like-candy-crush-with-spritekit-and-swift-part-1
首先,您应该为瓷砖和国际象棋创建一个辅助类Array <2D>。
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
}
}
}
您可以像这样创建自定义类Chess
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
}
}
要找到特定的点/区块,可以在游戏场景中使用以下辅助方法:
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)
}