このブログはPower Apps でローコーディングな勉強会 #14の資料その4になります。
このブログではキャラクターをステージに沿って移動させる方法についてご紹介致します。
キャラクターをステージの中に表示させる
キャラクターの初期位置をギャラリーのステージの中に設定します。
PlayerImage.X
_playerX + StageGallery.X - PlayerImage.Width / 8
PlayerImage.Y
_playerY + StageGallery.Y
こうすることで、ステージの左上端から2マス目に配置されてかと思います。
これでキャラクターがステージの中に配置されました!
キャラクターが壁やブロックをすり抜けないようにする
キャラクターが壁やブロックをすり抜けないようにするには、壁やブロックへ移動しようとしたときに座標を設定してある変数の値を変更しなければいいですね。
上記を踏まえて、UpButtonのOnselectのプレイヤーが移動するための処理を以下のように変更します。
UpButton.Onselect
If(CountIf( Filter(stage, RoundDown(_playerX / 48, 0) * 48 = X || (RoundDown(_playerX / 48, 0) + RoundUp(Mod(_playerX, 48) / 100, 0)) * 48 = X, RoundDown((_playerY - 12) / 48, 0) * 34 = Y || (RoundDown((_playerY - 12) / 48, 0) + RoundUp(Mod((_playerY - 12), 48) / 100, 0)) * 34 = Y), type <> 2) = 0, UpdateContext({_playerY:_playerY - 12}) );
急に複雑な式になってきましたね...
順番に解説を行っていきます。
まずは"Filter"部分の解説です。
Filterはstageに対して行っています。問題のフィルター対象ですが、
RoundDown(_playerX / 48, 0) * 48 = X || (RoundDown(_playerX / 48, 0) + RoundUp(Mod(_playerX, 48) / 100, 0)) * 48 = X
こちらでは、X座標に対するフィルターを行っています。
上の式はなんとなくわかるかと思います。現在のマスのX座標を取得していますね。
下の式は、プレイヤーが2マスにまたがっているときのための判定式です。
ボタンを1回押したときは、12だけ座標が変わるようにしていたかと思います。
そのため、プレイヤーが2マスにまたがっているときは2マス分の座標を取得して判定してあげる必要があります。
続いて、Y座標に対して行っているフィルターをみてみましょう。
RoundDown((_playerY - 12) / 48, 0) * 34 = Y || (RoundDown((_playerY - 12) / 48, 0) + RoundUp(Mod((_playerY - 12), 48) / 100, 0)) * 34 = Y)
X座標に対するフィルターの式と似ていますが、"- 12"が追加されていますね。
こちらは上ボタンを押したとき、プレイヤーは上に移動するので、その移動後の座標をフィルターするために追加しています。
CountIf( Filter(stage, RoundDown(_playerX / 48, 0) * 48 = X || (RoundDown(_playerX / 48, 0) + RoundUp(Mod(_playerX, 48) / 100, 0)) * 48 = X, RoundDown((_playerY - 12) / 48, 0) * 34 = Y || (RoundDown((_playerY - 12) / 48, 0) + RoundUp(Mod((_playerY - 12), 48) / 100, 0)) * 34 = Y), type <> 2)
こちらでは、フィルターされた結果の"type"が2以外の数をカウントしています。
"type"が2以外...つまりマップが床以外のものをカウントしています。
移動先が床以外であれば移動してはいけないので、"Countif() = 0"のときのみ移動するようにしています。
同様に下、右、左についても上記のような変更を施します。
参考までに、右の変更を記載しておきます。
RightButton.Onselect
If(CountIf( Filter(stage, RoundDown((_playerX + 12) / 48, 0) * 48 = X || (RoundDown((_playerX + 12) / 48, 0) + RoundUp(Mod((_playerX + 12), 48) / 100, 0)) * 48 = X, RoundDown(_playerY / 48, 0) * 34 = Y || (RoundDown(_playerY / 48, 0) + RoundUp(Mod(_playerY, 48) / 100, 0)) * 34 = Y), type <> 2) = 0, UpdateContext({_playerX:_playerX + 12}) );
こちらはX軸に移動するので、X座標のフィルターに"+ 12"の式がありますね。
あとは同じような処理を下、左の処理にも記載します。
ちなみにプレイヤーの移動も画像のサイズにあわせて移動するよう修正していますので、同じように修正しておいてください。
これでプレイヤーが壁をすり抜けたりしなくなりましたね!