Swiftで遊ぼう! - 724 - Sprite Kitを使ってシンプルゲーム作ってます
環境:Swift 3β
SKViewを実際に実装するためにSprite Kitを使ったシンプルゲームのチュートリアルに取り組んでいます。
SKViewはUIViewを継承していて、UIViewはUIResponderを継承しています。そういうわけで、UIResponderの次のメソッドをオーバライドして使えるんですが、このメソッドは何だ?
touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
なんて疑問に思ったんで、「Set」の復習をしました。しかし、このメソッド過去の記事で何の疑問も持たずに実装していました(^^;)
このメソッドでジェスチャーの1つ、「タッチ」を認識します。
guard let touch = touches.first else { return }
タッチをした場所をCGPoint型の値として抽出します。
let touchLocation = touch.location(in: self)
まず、プレーヤーの位置に手裏剣をセットします。まだ画面上に出現はしてません。
let projectile = SKSpriteNode(imageNamed: "projectile") projectile.position = player.position
さあ、ここからベクトル計算が入ってきます。SKViewの座標システムはUIViewの座標システムと異なります。画面の左下隅が(0, 0)です。タッチした位置がプレーヤーの位置から何処にあるか(相対的)示した値をオフセットと呼びます。素人はこういう言葉も知らなかったです。
let offset = touchLocation - projectile.position
プレーヤーより左側をタッチしたら何も生じないようにします。
if (offset.x < 0) { return }
プレーヤーより右側なら「手裏剣」は表示されます。
addChild(projectile)
offsetはCGPoint型で相対位置を示します。そして、「normalized()」というメソッドを使うのですが、CGPointの標準メソッドではありません。実は「Ewtension」を使ってCGPointを拡張させたメソッドなんです。Swiftの強力な機能の1つ「Extension」を節度を持って自由自在に使いかなせればSwiftプログラマーの有段者と言われています。ここでベクトル計算で重要なメソッドをCGPoint型に加えているんです。
extension CGPoint { func length() -> CGFloat { return sqrt(x*x + y*y) } func normalized() -> CGPoint { return self / length() } }
ということでnomalized()を使って方向を抽出します。お見事!
let direction = offset.normalized()
手裏剣が飛ぶ距離を設定します。画面の端から十分離れた距離をとります。
let shootAmount = direction * 1000
相対的な位置に実際の手裏剣の位置を加えて実際に飛ぶ位置を決めます。
let realDest = shootAmount + projectile.position
アクションを加えます。実際に飛んで行く位置に2.0秒で動くように設定します。
let actionMove = SKAction.moveTo(realDest, duration: 2.0)
アクション終了の挙動も設定するのが決まりです。
let actionMoveDone = SKAction.removeFromParent()
アクションを連続的に発生させないと動きになりません。
projectile.runAction(SKAction.sequence([actionMove, actionMoveDone]))
これで手裏剣の動きが完了です。この段階でランしても結構楽しめます。次は手裏剣がモンスターに接触した時の判定をしていきます。
今日はここまで。