ここでは「1日で基本が身に付く Swift アプリ開発超入門」の CHAPTER 8 P174〜177「敵を表示させるメソッドを作成しよう」について補足説明をします。
目次
P174 敵を表示させるメソッドを作成しよう
ここでは P174〜175 の「敵を表示させるメソッドを作成しよう」について補足説明をします。
リスト8-3は少し長いコードですが、処理を書く前は以下のようなとてもシンプルなコードで、didMove と moveEnemy の2つのメソッドだけです。
このうち didMove は初めから実装されている(書かれている)コードですので、新たに追加したのは、moveEnemy メソッドだけということになります。
import SpriteKit import GameplayKit class GameScene: SKScene { override func didMove(to view: SKView) { // 初期化処理をここに記述 } func moveEnemy() { // 的の表示と移動処理を記述 } }
didMove メソッドは、ゲーム開始時に一度だけ呼ばれるメソッドですので、ここに敵を表示して移動する処理を書いてしまうと、敵が一度しか表示されないことになってしまいます。
didMove メソッドは一度しか実行されませんが、リスト8-3の22行目に示したように1秒ごとに didMove メソッドを呼ぶようにしています。
このことを確認するために、以下のサンプルコードを入力して実行してみましょう。
ここでは、moveEnemyは「敵を表示」という文字列を Xcode のOutput エリアに表示するようにしています。didMoveメソッドでは1秒ごとに moveEnemy メソッドを呼び出しますので、1秒ごとに「敵を表示」という文字列が出力されます。
class GameScene: SKScene { var timer : Timer? override func didMove(to view: SKView) { timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { _ in self.moveEnemy() }) } func moveEnemy() { print("敵を表示") } }
実行結果は以下のようになります。
1秒ごとに moveEnemy を呼び出すメソッドについて
おそらく、didMove に書いた Timer.sheduledTimer が難しかったのではないかと思っています。
Timer.SheduledTImerメソッドは、以下の書式になっており3つの引数を持っています。
Timer.scheduledTimer(パラメータ1, パラメータ2, パラメータ3)
パラメータ1には、パラメータ3に書いた処理を呼び出す間隔(単位:秒)を書きます。上記のサンプルコードでは「1」と書いているので、1秒ごとに実行することになります。
パラメータ2には、パラメータ3に書いた処理を繰り返して実行するかどうかを指定します。true を指定すると何度も繰り返して実行をします。 false を指定した場合は1回のみ実行をします。
パラメータ3には、実行したい処理を書きます。処理は { _ in 〜 }の中に書きます。ここでは { _in didMove() } を書いています。
以上をまとめると、diMove メソッドを、1秒ごとに何度も実行する ということになります。
敵の表示について
敵の表示は moveEnemy メソッドで行うと説明しました。
敵の表示のみをするシンプルな例を以下に示します。
import SpriteKit import GameplayKit class GameScene: SKScene { var timer : Timer? override func didMove(to view: SKView) { timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { _ in self.moveEnemy() }) } func moveEnemy() { let enemy = SKSpriteNode(imageNamed: "enemy1") // 画像の読み込み addChild(enemy) // 読み込んだ画像の表示 } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { } }
敵の表示は16行目と17行目のコードで行なっています。
自機の表示方法と同じですので詳しくは説明しませんが、Assets.xcassets から「enemy1」の画像を読み込み、画面に表示しています。
上記を実行すると画面中央に敵を表示します。1秒ごとに何度も表示しますが、同じ場所に表示することになりますので、1機のみ表示しているように見えます。
P177 敵にアクションを設定する
本書のP177で説明している通り、画面に表示したキャラクターの移動アクションは、SKAction.MoveToメソッドで作成します。
この SKAction.MoveTo メソッドは現在のキャラクターの表示位置から指定した位置まで移動させるというものです。
また、表示したキャラクターを削除するアクションは SKAction.removeFromParent メソッドで作成します。
このようにして作成したアクションは、キャラクターと結びつけて実行する必要があります。これを実現しているのが、P175 の リスト8-3 の 47行目です。
キャラクターを格納した変数は、runメソッドを持っています。このrunメソッドの引数に作成したアクションを渡すことで、キャラクターが動きます。
本書では「enemy.run(SKAction.sequence([move, remove]))」としています。
SKAction.sequence はアクションを連結して、新しいアクションを作り出すものです。また、ここで使用している [] は配列を意味しており、カンマで区切ることでいくつものアクションを指定することができます。作成したアクションの move と remove を入れていますので、移動して削除をするという動きになります。
ちなみに、下に動くアクションと斜めに動くアクションを交互にしたアクションを作成すればジグザグに動くアクションを作成することもできます。
最後に、移動して消すだけのシンプルなサンプルコードを示します。 コードの説明はコメントを参照してください。
import SpriteKit import GameplayKit class GameScene: SKScene { var timer : Timer? override func didMove(to view: SKView) { timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { _ in self.moveEnemy() }) } func moveEnemy() { let enemy = SKSpriteNode(imageNamed: "enemy1") addChild(enemy) // 2秒かけて下に動くアクションを作成して move に入れる let move = SKAction.moveTo(y: -frame.height / 2, duration: 2.0) // 消すアクションを作成して remove に入れる let remove = SKAction.removeFromParent() // move と remove を実行する enemy.run(SKAction.sequence([move, remove])) } }
実行例を以下に示します。
まとめ
本書では、表示位置の設定や3種類の敵をランダムで表示していることもあり、コードは長くなっています。
実際には、敵を動かすだけであれば上記に示したコードを理解できれば十分です。
ここで覚えていただきたいのは以下となります。
- Timer.scheuledTimerメソッドの使い方
- SKAction.moveToメソッドによるキャラクターの移動
- SKAction.removeFromParentによるキャラクターの削除方法
- SKAction.sequenceでのアクションの連結
- runメソッドによるアクションの実行
上記を理解できれば、基本的なアクションを作ることができますので、ぜひ理解しましょう。