こんにちは!
出戻りガツオ🐟久しぶりの投稿です。
今回は、Power Appsのgalleryを使用した横スクロールゲームの操作の実現について
解説します!
動画はこんな感じ!
先にクレジットを表記
- 著作権 Loose Leaf
参照
- ドット絵世界
今回の内容の素材のほとんどがこちらから出てきます。
ご利用の際は必ず参照してください。
1. 必要なモノ
準備するもの一覧です。
- characterの画像
- 静止画 - 前向き
- 静止画 - 後ろ向き
- 静止画 - 右向き
- 静止画 - 左向き
- GIF画像- 前向き
- GIF画像 - 後ろ向き
- GIF画像 - 右向き
- GIF画像 - 左向き
- タイル
- 壁
- 草原など
- 透明の画像(なにも映っていないPNG)
行動を表現するうえでTimerコントロールを使って、動きを表現することもできます。
しかし、gif画像が断然ラクです。
iPhoneでも自動で作れますが、こちらのサイトでできますので、使って今回は実現しました。
さあ、材料をそろえたら始めましょう!
2. 構成
イメージとして二層構造にしています。
- 下地となるMap
- 動き回るキャラクター オブジェクト
他に装飾するオブジェクトは、無理にgalleryに乗せる必要はありません。
galleryのテンプレートサイズに合わせて、自由に載せていくだけで違和感は出ないからです。
ドラッグで動かしていくとズレやすいですが、数値単位1でXとYを修正すると、上手く配置できます。
大切なことは適切な場所に乗せていく感覚です。
MAP
空の水平ギャラリーでもかまいません。
マスの作り方ですが、TemplateSize
プロパティ(テンプレートのサイズ)を利用します。
これがマスの横幅に該当します。
そして縦幅はWrapCount
プロパティ(折り返しの数)で、行に分割することができます。
縦幅は、ギャラリー全体のHeight
プロパティ(縦幅)を等分に分割して算出できます。
ですので、ギャラリーの全体のHeight
プロパティ(縦幅)を、60 × 8 = 480とすることで
ギャラリーの各レコードが正方形になります。
ちなみに、ギャラリーの全体のWidth
プロパティ(横幅)も、60 * 横のマス数に設定されないと
美しく整いません。ですので、60 × 20 = 1200とします。
・ 表形式で整理!
コントロールは水平ギャラリー、親となるフレームになります。
プロパティ | Property | 値 | メモ |
---|---|---|---|
幅 | Width | 1200 | 60 * 横のマスの数(列数) |
高さ | Height | 480 | 60 * 縦のマスの数(行数) |
折り返しの数 | WrapCount | 8 | 縦のマスの数 |
テンプレートのサイズ | TemplateSize | 60 | マスの横幅 |
さて、この中でタイルの区分けをしていきたいと思います。
Sequence
関数で要素を見てみましょう。
Sequence(160)
タイルの区分け
移動させたくないエリアは下記の通りとします。※赤で塗りつぶされたマスです。
雑ですが、UpdateContext
で、赤で塗りつぶされたマスの番号を設定します。
UpdateContext(
{disableArea:
[
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 16, 17, 19, 21, 23, 24, 25, 27, 29, 32, 33,
40, 41, 48, 49, 56, 57, 60, 64, 65, 73, 74, 81, 89, 92, 93, 97, 104,
105, 112, 113, 120, 121, 126, 127, 128, 129, 132, 135, 136, 137, 140, 143, 144, 145,
148, 152, 153, 154, 155, 156, 157, 158, 159, 160
]
}
);
これによるメリットは、ギャラリーのデータソースItems
の中でも、インデックス番号をin
句で判定することにより、タイルの基本的な区分けが出来るからです。
- 移動可能なエリアに草原のタイル
- できないところに壁のタイル
となるようにしましょう。
1 まずは全マスに草原のタイルをImage
として最背面に配置する。
Imageコントロールを追加しています。縦横のサイズはTempleteSize
から書くのも良し、
直書きでも問題ないです。
注意点としてはImage
プロパティで画像の位置を拡大して表示にしておくとピタっとはまります。
2 次に必要なところに、壁か無色透明のImage
を乗せる
他のやり方もありそうですが、移動不可能なエリアをdisableArea
として宣言しています。
- 移動不可能なエリアに、壁のタイル
- それ以外に無色透明のタイル
こちらを乗せます。
無色透明な画像って意味がわからん表現ですよね。
PowerPointで、四角形の図形を書いて、塗りつぶしなし、枠線なしでpng
で図として保存すれば、それができます。
なんにも映らない透明な図の出来上がりです。
フォトで見ても何も映りません・・・
これで、草原タイルの上に乗せるイメージ(もといタイル)を変数でコントロールします。
-
disableArea
にインデックスが入っていたら壁のタイル - そうでなければ何も映らないタイル
とします。
こちらで下地ができあがります。
関数は以下の通りとなります。
// 移動できない範囲
UpdateContext(
{disableArea:
[
1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 24, 25, 32, 33,
40, 41, 48, 49, 56, 57, 64, 65, 73, 81, 89, 97, 104,
105, 112, 113, 120, 121, 128, 129, 136, 137, 144, 145,
152, 153, 154, 155, 156, 157, 158, 159, 160
]
}
);
// Collect関数でデータソースを追加方式で積み上げていく
ForAll(Sequence(160),
If(ThisRecord.Value in disableArea,
Collect(maps,{index: ThisRecord.Value,obj: wall}) ,
Collect(maps,{index: ThisRecord.Value,obj: _null})
)
);
ゲーム画面のOnVisible
にClearCollect
関数を上記にまず書くことがStep1です。
各レコードのvisible
プロパティの制御でもできそうですが、なんとなく今回はこうしました。
メインキャラクターの移動
移動を表すために、Mapと同様の水平ギャラリーを用意します。
データソースItems
はこちらです。
// ###########################
// All Null
// ###########################
ForAll(
Sequence(160),
Collect(moves,
{index: ThisRecord.Value,obj: _null})
);
// ###########################
// Init
// ###########################
UpdateContext(
{
_index:68,
_me:front
}
);
// こちらで初期の位置を制御
Patch(moves,First(Filter(moves,index=_index)),{obj:_me});
データソースが異なるだけで、
- X
- Y
- Height
- Width
これらのプロパティ値は、Mapと全て同様です。
Patch
関数で主人公キャラクターの初期の位置と画像を表しています。
Mapの上にこのようなギャラリーを乗せるイメージになります。
重なるとこうなります。
それらしいですね。
さて、これに動きをつけたりするなど、ゲームらしい要素を追加していきたいところですが、
結構長くなってきたので、一旦ここまでとします。
動きの部分については次のステップで解説したいと思います。
それでは皆様、良いPower Apps Lifeを!