Swiftで遊ぼう! - 894 - 話はとびまくりGameplayKitチュートリアルに戻ります
- Swiftで遊ぼう!の前書き-> Life-LOG OtherSide
- 初心者はここから!-> 50オヤジでもできるiOS開発
- 私の本業、オフィシャルなブログ-> Life-LOG
- Swift 3 対応
人様が作ったチュートリアルに取り組んでいると、最近不満に思うことが増えています。「もう少しツッコんだ説明が欲しいな」とか「もう少し実践的なコーディングの説明ないかな」なんて思います。
GameplayKitのチュートリアルも少々古く、iOS10で加わった新しい機能を追加して改訂してくれたらいいのにな、なんて不満があって途中で止めてしまいそうになりましたが。何が何でも続けるという信条でPathfindingの説明を続けます。
MovementComponentを作ったので、これをEntityに加えます。新しい敵キャラ(赤いスクエアですが)をEntityとして登録します。
GameScene.swiftの冒頭に次のプロパティを登録します。
var enemies = [GKEntity]()
GKEntityタイプの空のアレーを用意します。
次に「createGrid()」メソッドの下に次のコードを加えます。
func createEnemies() { }
ここで敵entityを作って、画面の左端から右端のゴールに向かって動いてもらいます。
let enemy = GKEntity() let gridPosition = int2(0, Int32(height) / 2) let destination = int2(Int32(width) - 1, Int32(height) / 2)
gridPositionはenemyの現在位置と言っていいでしょう。画面左端の真ん中からスタートします。destinationは目的地となります。どちらの値もint2型で、GKGridGraphの座標系です。
実際に画面に表示をするためにSKSpriteNodeが必要になります。
let sprite = SKSpriteNode(color: UIColor.red, size: CGSize(width: boxSize * 0.6, height: boxSize * 0.6)) sprite.position = pointFor(coordinate: gridPosition)
spriteはただの赤い箱です。位置情報は、int2型からCGPoint型に変換するメソッド「pointFor(coordinate:)」を使います。
SKViewに表示することと、GKGridGraphに表示することが異なることを理解しておく必要があります。<-このやり方が違うような気がするんですがどうなんでしょう?
どちらにしろ次のコーディングは、GKGridGraphに表示させるためにMovementComponentインスタンスを作ります(VisualCompanentを継承してるからです)。そして移動先も登録します。
let movementComponent = MovementComponent(scene: self, sprite: sprite, coordinate: gridPosition, destination: destination)
このコンポーネントを敵entityに登録します。
enemy.addComponent(movementComponent)
そして、このenemyをenemiesに登録します。
enemies.append(enemy)
これでエンティティは用意されたけど、実際SKViewでは何も生じません。次はSKSpriteKitを使って、画面上で動きを表示させるステップです。
var sequence = [SKAction]()
アクションの入れ籠を用意します。複数の敵キャラに動きを対応するためです。今のところenemyは1つだけですが、次のようにループを実行させます。
for enemy in enemies { let action = SKAction.run { [unowned self] in let movementComponent = enemy.component(ofType: MovementComponent.self)! self.addChild(movementComponent.sprite) // updateは後で追加 // 一時的に以下のコードを加えて動作チェック let path = movementComponent.pathToDestination() movementComponent.followPath(path: path) } let delay = SKAction.wait(forDuration: 2) sequence += [action, delay] }
タワーが設置されることで、パスファインディングの再計算をさせてupdateさせないといけませんが、今は、ちゃんと敵が動くかどうか確認するためにMovementComponentの「followPath()メソッドを使ってActionシークエンスを実行させてみます。
このコードを「didMove(to view: SKView)」に組み込みます。
override func didMove(to view: SKView) { createGrid() graph = GKGridGraph(fromGridStartingAt: int2(0, 0), width: Int32(width), height: Int32(height), diagonalsAllowed: false) createEnemies() }
これでランすると、赤い箱が画面の左端から右端に動いていきます。
まだupdateが実装されていないので、進行方向にタワーを設置してもすり抜けていきます。
今日はここまで。