はじめに
前回の続きです。
今回はステージを作っていきます。
素材準備
背景(ちょっと適切なサイズがわからない。。。)
床ブロック
実装
今回も SKScene の実装のみです。今回は全部コードで実装してますが SpriteKit Scene などのファイルを追加すれば GUI でも操作可能です。
背景表示
背景を表示します。
final class GameScene: SKScene {
override func didMove(to view: SKView) {
let backNode = SKSpriteNode(imageNamed: "background")
backNode.size = frame.size
backNode.position = .init(x: frame.midX, y: frame.midY)
addChild(backNode)
}
}
こんな感じです。
床表示
SKTileMapNode
を使って床を作ります。
final class GameScene: SKScene {
private let tilePositions: [(column: Int, row: Int)] = [
(0, 0), (0, 1),
(1, 0), (1, 1),
(2, 0), (2, 1),
(3, 0), (3, 1),
(4, 0), (4, 1),
(5, 0), (5, 1),
(6, 0), (6, 1), (6, 2),
(7, 0), (7, 1), (7, 2), (7, 3),
(8, 0), (8, 1),
(9, 0), (9, 1),
(10, 0), (10, 1),
(11, 0), (11, 1),
(12, 0), (12, 1),
(13, 0), (13, 1),
(14, 0), (14, 1),
(15, 0), (15, 1),
(16, 0), (16, 1),
(17, 0), (17, 1),
(18, 0), (18, 1),
(19, 0), (19, 1),
(20, 0), (20, 1),
(21, 0), (21, 1),
(22, 0), (22, 1),
(23, 0), (23, 1),
(24, 0), (24, 1),
(25, 0), (25, 1),
(26, 0), (26, 1),
(27, 0), (27, 1),
(28, 0), (28, 1),
(29, 0), (29, 1),
(30, 0), (30, 1),
(31, 0), (31, 1),
(32, 0), (32, 1),
(33, 0), (33, 1),
(34, 0), (34, 1),
(35, 0), (35, 1),
(36, 0), (36, 1),
(37, 0), (37, 1),
(38, 0), (38, 1),
(39, 0), (39, 1),
(40, 0), (40, 1),
(41, 0), (41, 1),
(42, 0), (42, 1),
(43, 0), (43, 1),
(44, 0), (44, 1),
(45, 0), (45, 1),
(46, 0), (46, 1),
(47, 0), (47, 1),
(48, 0), (48, 1),
(49, 0), (49, 1),
]
override func didMove(to view: SKView) {
let tileSize = CGSize(width: 32, height: 32)
let group = SKTileGroup(tileDefinition: .init(texture: .init(imageNamed: "tile_block"), size: tileSize))
let tileSet = SKTileSet(tileGroups: [group])
let tileMap = SKTileMapNode(tileSet: tileSet, columns: tilePositions.last!.column + 1, rows: 4, tileSize: tileSize)
tilePositions.forEach {
tileMap.setTileGroup(group, forColumn: $0.column, row: $0.row)
}
tileMap.position = .zero
tileMap.anchorPoint = .zero
addChild(tileMap)
// physicsBody設定
tilePositions.forEach {
let node = SKSpriteNode()
node.position = .init(x: CGFloat($0.column) * tileSize.width + tileSize.width/2,
y: CGFloat($0.row) * tileSize.height + tileSize.height/2)
node.physicsBody = .init(rectangleOf: tileSize)
node.physicsBody?.isDynamic = false
tileMap.addChild(node)
}
}
}
こんな感じです。
ちょっと解説。tilePositions
がタイルの位置を表していて(0, 0)が左下のタイルになります。下記で設定する columns
と rows
は横と縦の最大値になります。今回は横に 50, 縦に(最大で)4 並べるのでその数値をそれぞれ設定しています。
let tileMap = SKTileMapNode(tileSet: tileSet, columns: tilePositions.last!.column + 1, rows: 4, tileSize: tileSize)
下記の設定は床を画面の左下起点に置きたかったのでそれぞれ .zero
を設定しています。
tileMap.position = .zero
tileMap.anchorPoint = .zero
下記の処理は SKTileMapNode
にいい感じに physicsBody
を設定する方法がない(たぶん)のでタイル1つ1つに physicsBody
設定しています。
tilePositions.forEach {
let node = SKSpriteNode()
node.position = .init(x: CGFloat($0.column) * tileSize.width + tileSize.width/2,
y: CGFloat($0.row) * tileSize.height + tileSize.height/2)
node.physicsBody = .init(rectangleOf: tileSize)
node.physicsBody?.isDynamic = false
tileMap.addChild(node)
}
おわりに
前回のと合わせるとこんな感じになります。
偶然にもどこかでみたことのあるようなステージになってしまいました
次回は横スクロールできるようにします!
SpriteKit あまりさわったことないのでもっといい方法あればぜひ教えて下さい