読者です 読者をやめる 読者になる 読者になる

Swiftで遊ぼう! on Hatena

あしたさぬきblogでやってた初心者オヤジのiOSプログラミング奮闘記がHatenaに来ました

Swiftで遊ぼう! - 896 - チュートリアルやっと終了に向かって...

やっとGameplayKitの古い*1チュートリアルもやった終盤に入ります。

最後の課題は、Pathfindingを使って得られる道筋の描画用のSKNodeを用意します。GameScene.swiftの冒頭で宣言。

var pathLine: SKNode!

宣言をしたら初期化が必須です。カスタムクラスならinit()イニシャライザーで書くのですが、フレームワークの使用では、多くの場合、初期化メソッドが用意されています*2。SKSceneクラスの場合、didMove(to view: SKView)メソッドなので、次のコードを加えます。

pathLine = SKNode()
addChild(pathLine)

これで受け皿は用意できました。ここにpathLineに描画すれば、画面に出現するわけです。

パスラインを描画しるメソッドを用意します。

func updateVisualPath(path: [GKGridGraphNode]) {
    // 1
    pathLine.removeAllChildren()
    // 2
    var index = 0
    // 3
    for node in path {
        // 4
        let position = 
            pointFor(coordinate: node.gridPosition)
            
        if index + 1 < path.count {
            // 5
            let nextPosition = 
          pointFor(coordinate: path[index + 1].gridPosition)
            // 6
            let bezierPath = UIBezierPath()
            let startPoint = 
                CGPoint(x: position.x, y: position.y)
            let endPoint = 
                CGPoint(x: nextPosition.x, y: nextPosition.y)
            bezierPath.move(to: startPoint)
            bezierPath.addLine(to: endPoint)
            // 7
            let pattern: [CGFloat] = 
                [CGFloat(boxSize / 10), CGFloat(boxSize / 10)]
            // 8
            let dashed = 
                CGPath.init(__byDashing: bezierPath.cgPath, 
                              transform: nil, 
                                  phase: 0, 
                                lengths: pattern, 
                                  count: 2)!
            // 9
            let line = SKShapeNode(path: dashed)
            line.strokeColor = UIColor.black
            pathLine.addChild(line)

        }
        // 10
        index += 1
    }
}

このメソッドを、読んでコードがスラスラと分かるようなら、あなたのプログラミングレベルは中級です。もし、理解できなければまだまだ初級の域を脱していないってことで、コードの説明に入ります。

  1. まずpathLineに加えた全てのノードを除去します。
  2. ここのpathは[GKGridGraphNode]のことで、このクラス出持っているプロパティ「graph」のことで、nodeのパス情報を持っていることになります。そして、indexを「0」にしているのは、このアレー型のパス情報にいくつのnodeがあるかカウントするために使用します。
  3. そしてpathにある個々のnodeで作業するためにforループを使って要素を抜き出します。
  4. nodeの位置情報はint2型なので、描画のためのCGPoint型に変換。
  5. 次に移動すべきnodeの位置をCGPont型に変換してnextPositionに保持させます。
  6. UIBezierPathを使って*3今いるnodeの中点から次のnodeを中点へ線を書きます。
  7. 実践を点線に変更 <- これが理解できない
  8. この現在のnodeから次のnodeに引くBezierPathを使って、SKShapeNodeのインスタンスにして、pathLineに加えます。
  9. pathにあるすべてのnodeを繋げていく点線をpathLineに保持させます。

とこういう流れです。

ちょっと分からない「8」のステップは明日のエントリーに。

*1:iOS 9で最初に紹介されたPathfindingの説明なんで...

*2:初期化メソッドの使用が推奨されている理由は次 -> Swiftで遊ぼう! - 248 - UIViewの初期化ステップ - Swiftで遊ぼう! on Hatena

*3:UIBezierPathの基本事項 -> Swiftで遊ぼう! - 251 - draw: UIBezierPath - Swiftで遊ぼう! on Hatena