このブログはPower Apps でローコーディングな勉強会 #14の資料その10になります。
このブログではエネミーを表示し、エネミーを動かす方法についてご紹介致します。
エネミーを表示する
これまでと同様の方法でPower Apps に敵のイメージを読み込んで、Power Apps に画像を表示してください。
表示させる画像は、縦移動用の素材のイメージは前方向に進んでいるイメージと後ろ方向に進んでいるイメージを1つずつ。
横移動用の素材のイメージは左方向に進んでいるイメージと右方向に進んでいるイメージを1つずつ。計4つのイメージを表示させてください。
エネミーを移動させる
今回紹介するエネミーの移動方法には「ブロックを判定しない」という制限があります。
以下で紹介する実装方法をみてもらえればわかるかと思いますが、移動範囲は一定なので、予めブロックと被らない箇所にエネミーの初期位置を設定してください。
縦移動するエネミー
縦移動を行うエネミーの実装方法についてご紹介します。
こちらで紹介するのは最初下方向に移動し、ある一定の行動範囲まで移動したら反転し、上方向に移動するを繰り返すエネミーの実装方法についてです。
縦方向のみの移動ですので、X成分は固定値でいいですね。
適当な箇所を初期位置とし、エネミーをステージの中に配置してください。
続いてY成分ですが、こちらはタイマーを用いて値を変化させようと思います。
なので、タイマーをキャンバス内に追加し、時間を保持する変数を宣言します。
Screen1.OnVisible
UpdateContext({_time:0});
Timer.Duration
10
Timer.OnTimerEnd
UpdateContext({_time:_time + 1})
これで10ミリ秒ごとに"time"変数に+1ずつ値が加算されていきます。
こちらの"time"をエネミーのYに適応していきます。
値Xが一定で増えていく場合、どのような式を適応すれば値Yは特定の範囲の値をとるでしょうか?
・・・
そう!等速円運動のY成分の式ですね!!
例えば、半径をr、角度をθとすると、X, Yはそれぞれ以下のように表せますね。
X = r cos(θ)
Y = r sin(θ)
こちらのYの式を適応します。
Enemy1_1Image.Y
// 等速円運動のY成分 340 + Sin(_time / 30) * 150
上記式は、「初期位置 + 等速円運動のY成分の式」となっており、「/ 30」は移動速度を、「* 150」は移動範囲を表しています。
今回の設定でいうと6マス分移動します。
ただこのままでは初期位置のときSinの式は0になっていますが、最低値は-150をとりますね。
なので、初期位置、つまり"_time"が0のときSin() = -1となるようにしたいと思います。
Sin(θ) = -1
θ = ASin(-1)
θ = -90
ですので、()の中の式が-90となるようにすればいいです。
ただし、こちらの関数はdegではなくradを用いて計算を行っているので、radに直してあげる必要があります。
degとradの関係式は以下ですね。
1[deg] = Pi() / 180[rad]
これらをもとに上記の式を修正してみましょう。
Enemy1_1Image.Y
// 等速円運動のY成分 340 + Sin(_time / 30 - 90 * Pi() / 180) * 150
これで上下に動くエネミーの作成ができました!
余力のあるかたは、最初に上方向へ移動を開始するエネミーも実装してみましょう。
横移動するエネミー
横移動を行うエネミーの実装方法についてご紹介します。
こちらで紹介するのは最初左方向に移動し、ある一定の行動範囲まで移動したら反転し、右方向に移動するを繰り返すエネミーの実装方法についてです。
横移動の実装方法も縦移動の実装方法とほとんど同じです。
縦移動は等速円運動のY成分の式を使用しましたが、横移動はX成分の式を使用するだけですね。
なので、エネミーの初期位置をステージ内に配置後以下のようにXを設定します。
Enemy2_1Image.X
855 + Cos(_time / 30) * 150
こちらに関してはCos(0) = -1で最低値をとりますので、初期位置の調整は特にいらないですね。
余力のあるかたは、最初に右方向へ移動を開始するエネミーも実装してみましょう。
エネミーにアニメーションを実装する
このままですと敵の画像がただ動いているだけなので、アニメーションを実装しましょう。
例えば縦方向に移動するエネミーを例にとると、前進中は前を向いているアニメーションを、後進中は後進しているアニメーションのみを表示したいですね。
それを判定するためには、今回はsinとcosを用いているので、周期で判断すればいいですね。
RoundDown(Mod((_time / 30) / Pi(), 2), 0)
こちらの式で実現できます。余りが0のときが最初の方向への移動、余りが1のときが折り返し方向への移動になります。
また、さらにこの場合のときにそれぞれのアニメーションを表示したいですね。
なので以下のように設定します。
Enemy1_1Image.Image
Switch(RoundDown(Mod((_time / 30) / Pi(), 2), 0), 0, Switch(RoundDown(Mod(_time / 10, 3), 0), 0, Enemy1Image_0, 1, Enemy1Image_1, 2, Enemy1Image_2), 1, Switch(RoundDown(Mod(_time / 10, 3), 0), 0, Enemy1Image_3, 1, Enemy1Image_4, 2, Enemy1Image_5))
これで、アニメーションの設定は完了です!
他のエネミーに関しても同様にアニメーションの設定を行ってください。