【Swift】SpriteKitの使い方。シェイプノードを使って多角形や円を描画する。(Swift 2.2、XCode 7.3)
SKShapeNodeとは
本記事ではSpriteKit Sceneファイルの編集画面(シーンエディタ)で設定できるSKShapeNode(以下、シェイプノード)について説明する。
シェイプノードとは、多角形や円などの図形をシーンに描画するノードである。
ベタ塗りの図形を描画することが多いので、主に画像を表示するSKSpriteNodeより高速かと思いきや、パフォーマンスはSKSpriteNodeのほうが高いようなことが公式リファレンスに記載されている。
⇒公式リファレンス「SKShapeNode」
the SKSpriteNode class offers higher performance than this class, so use shape nodes sparingly.
シェイプノードを使ってみる
実際にシーンに図形を描画してみよう。以降の手順を行う前のXcodeプロジェクトをGitHubに置いたので、試してみる方はご利用下さい。⇒「テスト用プロジェクト」
事前準備ではタップすると重力を受けて落下する鳥ノードをSpriteKit Sceneファイル(以下、SKSファイル)に配置しておいた。
下図赤枠のSKSファイルを選択してシーンエディタを開く。黄緑枠のオブジェクトライブラリボタンを押して部品一覧を表示し、ドラッグ&ドロップで「Shape Node(Square)」をシーンに配置する(紫矢印)。
黄枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Stroke Colorに赤色、Fill Colorに青色を設定する。
以下は実際のプレイ動画
設定項目を説明する
アトリビュートインスペクタの設定項目を1つずつ説明する。
Name
ノードの名前を設定する。ソースコードからこのノードにアクセスするときの識別子になる。また、他ノードでParentを指定するときに使われる。
Parent
親ノードを設定する。デフォルトではシーン名が設定されている。
子ノードは親ノードと同じ動きをする。例えば、親ノードが回転すると子ノードも一緒に回転する。
Position
ノードの座標を設定する。シーンに配置されているノードをドラッグ&ドロップで運ぶと、この設定値も自動で更新される。
Z Position
ノードのZ軸の位置を指定する。SKSpriteNodeと意味は同じ。⇒「Z Positionとは」
Rotation
ノードの回転角度を設定する。アンカーポイントを中心に、指定した角度で回転したノードが表示される。
Scale
配置したときの四角形のX方向とY方向大きさをそれぞれ1として、表示する図形の大きさをの倍率で設定する。マイナスは設定できない。
Stroke Color
線の色を設定する。
Fill Color
図形を塗りつぶす色を設定する。
Line Width
線の太さを設定する。
Glow Width
アンチエイリアスで描かれている半透明の線の太さを設定する。アンチエイリアスがOFFになっている場合は描画されない。
Alpha
図形の透過度を設定する。0は完全に見えなくなり、0.5は半透明、1.0以上は透過されずに見える。
Antialiased
チェックを入れると線にアンチエイリアスが適用される。
アンチエイリアスとは、境界線のギザギザ感を目立たなくするために境界線に沿って描く中間色のことをいう。これによって、曲線が滑らかに見える。
Stroke Texture
線を画像にする場合に設定する。下図は鳥の画像を設定した場合。
Fill Texture
図形の塗りつぶしを画像にする場合に設定する。下図は背景画像を設定した場合。
円を描画する
SKSファイルで配置するシェイプノードは長方形しか描画することができない。なので、長方形以外の多角形や円形を描画したい場合はソースコードで実装する。
例えば、タップした位置に半径60ポイントの円を描画するにはTestScene.swiftのtouchesBeganメソッドを以下のように変更する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
//画面タッチ時の呼び出しメソッド override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { //タッチした座標のノードを取得する。 let location = touches.first!.locationInNode(self) let node = nodeAtPoint(location) as! SKSpriteNode //鳥ノードの場合、物理ボディを設定する。 if(node == birdBrown){ node.physicsBody?.affectedByGravity = true } else { //円形のシェイプノードを作成する。 let circle = SKShapeNode(circleOfRadius: 60.0) circle.position = CGPointMake(location.x, location.y) circle.strokeColor = SKColor.blackColor() circle.fillColor = SKColor.grayColor() //シーンに追加する。 self.addChild(circle) } } |
以下は実際のプレイ動画。鳥以外の場所をタップすると円が描画される。
物理ボディを設定する
シェイプノードもSKSpriteNodeと同様に物理ボディを設定して衝突させたり、重力の影響を受けさせたりできる。ただし、SKSファイルでは設定できない。
TestScene.swiftのtouchesBeganメソッドに物理ボディの設定を追加した。
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 |
//画面タッチ時の呼び出しメソッド override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { //タッチした座標のノードを取得する。 let location = touches.first!.locationInNode(self) let node = nodeAtPoint(location) as! SKSpriteNode //鳥ノードの場合、物理ボディを設定する。 if(node == birdBrown){ node.physicsBody?.affectedByGravity = true } else { //円形のシェイプノードを作成する。 let circle = SKShapeNode(circleOfRadius: 60.0) circle.position = CGPointMake(location.x, location.y) circle.strokeColor = SKColor.blackColor() circle.fillColor = SKColor.grayColor() //物理ボディを設定する。 circle.physicsBody = SKPhysicsBody(circleOfRadius: 60.0) circle.physicsBody?.dynamic = false //シーンに追加する。 self.addChild(circle) } } |
以下は実際のプレイ動画
多角形を描画する
タップ位置を頂点とした多角形を描画するにはTestScene.swiftを以下のコードに変更する。鳥ノードをタップした段階で、物理ボディが設定された多角形を描画している。
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 |
// // TestScene.swift // import Foundation import SpriteKit class TestScene:SKScene { var birdBrown:SKSpriteNode! var path = CGPathCreateMutable() //現在シーン設定時の呼び出しメソッド override func didMoveToView(view: SKView) { //SKSファイルに配置した鳥ノードを取得する。 birdBrown = self.childNodeWithName("bird_brown") as? SKSpriteNode } //画面タッチ時の呼び出しメソッド override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { //タッチした座標のノードを取得する。 let location = touches.first!.locationInNode(self) let node = nodeAtPoint(location) as! SKSpriteNode //鳥ノードの場合、物理ボディを設定する。 if(node == birdBrown){ //鳥ノードに物理ボディを設定する。 node.physicsBody?.affectedByGravity = true //パスを閉じる。 CGPathCloseSubpath(path) //多角形のシェイプノードを作成する。 let polygon = SKShapeNode(path: path) polygon.strokeColor = SKColor.blackColor() polygon.fillColor = SKColor.grayColor() //シェイプノードに物理ボディを設定する。 polygon.physicsBody = SKPhysicsBody(polygonFromPath: path) polygon.physicsBody?.dynamic = false //シェイプノードをシーンに追加する。 self.addChild(polygon) } else { if(CGPathIsEmpty(path) == true){ //パスが空の場合、タップ位置を始点にする。 CGPathMoveToPoint(path, nil, location.x , location.y) } else { //パスが空ではない場合、タップ位置をパスに追加する。 CGPathAddLineToPoint(path, nil, location.x , location.y) } } } } |
以下は実際のプレイ動画