【Swift】SpriteKitの使い方。SKTileDefinitionを使ってタイルの画像を反転、回転したり、パラパラアニメのように切り替える。
SKTileDefinitionとは
本記事では、SKTileDefinition(以下、タイル定義)について説明する。タイル定義とは、SKTileMapNode(以下、タイルマップノード)のマスに配置するタイルの設定を行うためのクラスである。
タイルの画像を反転、回転させたり、パラパラアニメのように画像を変化させるときに利用する。
タイル定義を使ってみる
以降の手順を行う前のXcodeプロジェクトをGitHubに置いたので、試してみる方はご利用下さい。⇒「テスト用プロジェクト」
事前準備では、タイルマップノードをシーンに配置し、桜の木を咲かせておいた。
下図赤枠の「TestTile.sks」を選択、青枠の「center」を選択、黄緑枠のアトリビュートインスペクタボタンを押して設定画面を表示する。これがタイル定義の設定画面である。
Name
タイル定義の名前。ソースコードからアクセスするための識別子に用いる。
Textures
タイルの画像。複数の画像を設定すればパラパラアニメのように変化させることができる。
実際にやってみよう。下図赤枠のメディアライブラリボタンを押して画像一覧を表示する。Ctrlキーを押しながら一覧の中の「sakura2」、「sakura3」、「sakura4」を選択し、ドラッグ&ドロップでTexturesまで運ぶ(青矢印)。
紫枠のTime Per Frameを「0.5」に変更する。
シュミレーターを起動すると以下の動画のようになる。
Size
タイルのサイズ。W(Width)は幅、H(Height)は高さ。
Placement Weight
Variant Definitionに複数のタイルを設定した場合、この設定値の数字が大きいタイルのほうが配置される確率が高くなる。
Rotation
タイルの画像を回転する。回転角度の選択肢は90度、180度、270度の3択。
下図は270度を設定した結果。
Flip Vertically
タイルの画像を垂直方向に反転する。
Flip Horizontally
タイルの画像を水平方向に反転する。今回の桜では変化が分からない。
ソースコードでタイル定義を実装する
ちなみに、ソースコードでタイル定義を実装するには以下のコードのようにする。TileSetファイルは利用せずに実装した。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
// // TestScene.swift // import Foundation import SpriteKit class TestScene:SKScene { //現在シーン設定時の呼び出しメソッド override func didMove(to view: SKView) { //テクスチャを作成する。 let texture2 = SKTexture(imageNamed: "sakura2") let texture3 = SKTexture(imageNamed: "sakura3") let texture4 = SKTexture(imageNamed: "sakura4") //タイル定義を作成する。 let definition = SKTileDefinition(textures: [texture2,texture3,texture4], size: CGSize(width:50, height:50), timePerFrame: 1.0) //画像を垂直方向に反転させる。 definition.flipVertically = true //タイルグループを作成する。 let tileGroup = SKTileGroup(tileDefinition: definition) //タイルセットを作成する。 let tileSet = SKTileSet(tileGroups: [tileGroup]) //タイルマップノードを作成する。 let tileMapNode = SKTileMapNode(tileSet:tileSet, columns:12, rows:12, tileSize:CGSize(width:50, height:50)) //タイルマップノードの座標画面中央 tileMapNode.position = CGPoint(x: self.frame.midX, y: self.frame.midY) //タイルマップノードを作成したタイルグループで埋め尽くす。 tileMapNode.fill(with: tileGroup) //シーンにタイルマップノードを追加する。 self.addChild(tileMapNode) } } |
以下は実際のプレイ動画
ソースコードで8-Way Adjacency Groupを実装する。
さらにちなみに、8方向隣接グループをソースコードで実装するには以下のコードのようにする。13個のタイル定義を作成するのは結構時間がかかった。
(・□・;)フゥー
素直にTileSetファイルを利用したほうが良さそうだ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
// // TestScene.swift // import Foundation import SpriteKit class TestScene:SKScene { //タイルを配置する場所 let tilePos = [(2,2),(2,3),(2,8),(2,9),(2,10),(2,11), (3,3),(3,4),(3,8),(3,9), (4,3),(4,4),(4,5),(4,9), (5,4),(5,5),(5,9), (6,4),(6,5),(6,9), (7,4),(7,5),(7,6),(7,8),(7,9), (8,6),(8,7),(8,8),(8,9),(9,7)] //現在シーン設定時の呼び出しメソッド override func didMove(to view: SKView) { //中央 let centerDefintion = SKTileDefinition(texture: SKTexture(imageNamed: "center")) let centerRule = SKTileGroupRule(adjacency: .adjacencyAll, tileDefinitions: [ centerDefintion ]) //上 let upEdgeDefinition = SKTileDefinition(texture: SKTexture(imageNamed: "up_edge")) let upEdgeRule = SKTileGroupRule(adjacency: .adjacencyUpEdge, tileDefinitions: [ upEdgeDefinition ]) //下 let downEdgeDefinition = SKTileDefinition(texture: SKTexture(imageNamed: "down_edge")) let downEdgeRule = SKTileGroupRule(adjacency: .adjacencyDownEdge, tileDefinitions: [ downEdgeDefinition ]) //左 let leftEdgeDefintion = SKTileDefinition(texture: SKTexture(imageNamed: "left_edge")) let leftEdgeRule = SKTileGroupRule(adjacency: .adjacencyLeftEdge, tileDefinitions: [ leftEdgeDefintion ]) //右 let rightEdgeDefintion = SKTileDefinition(texture: SKTexture(imageNamed: "right_edge")) let rightEdgeRule = SKTileGroupRule(adjacency: .adjacencyRightEdge, tileDefinitions: [ rightEdgeDefintion ]) //左上 let upperLeftEdgeDefinition = SKTileDefinition(texture: SKTexture(imageNamed: "upper_left_edge")) let upperLeftEdgeRule = SKTileGroupRule(adjacency: .adjacencyUpperLeftEdge, tileDefinitions: [ upperLeftEdgeDefinition ]) //右上 let upperRightEdgeDefinition = SKTileDefinition(texture: SKTexture(imageNamed: "upper_right_edge")) let upperRightEdgeRule = SKTileGroupRule(adjacency: .adjacencyUpperRightEdge, tileDefinitions: [ upperRightEdgeDefinition ]) //左下 let lowerLeftEdgeDefinition = SKTileDefinition(texture: SKTexture(imageNamed: "lower_left_edge")) let lowerLeftEdgeRule = SKTileGroupRule(adjacency: .adjacencyLowerLeftEdge, tileDefinitions: [ lowerLeftEdgeDefinition ]) //右下 let lowerRightEdgeDefinition = SKTileDefinition(texture: SKTexture(imageNamed: "lower_right_edge")) let lowerRightEdgeRule = SKTileGroupRule(adjacency: .adjacencyLowerRightEdge, tileDefinitions: [ lowerRightEdgeDefinition ]) //左上コーナー let upperLeftCornerDefinition = SKTileDefinition(texture: SKTexture(imageNamed: "up_left_corner")) let upperLeftCornerRule = SKTileGroupRule(adjacency: .adjacencyUpperLeftCorner, tileDefinitions: [ upperLeftCornerDefinition ]) //右上コーナー let upperRightCornerDefinition = SKTileDefinition(texture: SKTexture(imageNamed: "up_right_corner")) let upperRightCornerRule = SKTileGroupRule(adjacency: .adjacencyUpperRightCorner, tileDefinitions: [ upperRightCornerDefinition ]) //左下コーナー let lowerLeftCornerDefinition = SKTileDefinition(texture: SKTexture(imageNamed: "lower_left_corner")) let lowerLeftCornerRule = SKTileGroupRule(adjacency: .adjacencyLowerLeftCorner, tileDefinitions: [ lowerLeftCornerDefinition ]) //右下コーナー let lowerRightCornerDefinition = SKTileDefinition(texture: SKTexture(imageNamed: "lower_right_corner")) let lowerRightCornerRule = SKTileGroupRule(adjacency: .adjacencyLowerRightCorner, tileDefinitions: [ lowerRightCornerDefinition ]) //作成したルールを引数にタイルグループを作成する。 let tileGroup = SKTileGroup(rules: [centerRule, upEdgeRule, downEdgeRule, leftEdgeRule,rightEdgeRule, upperLeftEdgeRule, upperRightEdgeRule, lowerLeftEdgeRule, lowerRightEdgeRule, upperLeftCornerRule, upperRightCornerRule, lowerLeftCornerRule, lowerRightCornerRule]) //タイルセットを作成する。 let tileSet = SKTileSet(tileGroups: [tileGroup]) //タイルマップノードを作成する。 let tileMapNode = SKTileMapNode(tileSet:tileSet, columns:12, rows:12, tileSize:CGSize(width:50, height:50)) //タイルマップノードの座標画面中央 tileMapNode.position = CGPoint(x: self.frame.midX, y: self.frame.midY) //マスにタイルを配置する。 for pos in tilePos { tileMapNode.setTileGroup(tileGroup, forColumn:pos.0, row:pos.1) } //シーンにタイルマップノードを追加する。 self.addChild(tileMapNode) } } |
下図は実行結果