Power Apps でゲームを作る~ブロックを自在に並べる~ #Power Platformリレー

こんにちは! Power Platform App Maker Associate のサトハルです。

「アプリメイカー」って響きがカッコよくて好きです(?)

前回はブロック崩しの前提であるボールの移動と壁との反射を作りました。

今回はブロック崩しにおいてボールと双璧をなす重要アイテムであるブロックを作っていこうと思います。

長くなったのでボールとブロックの接触ロジックに関しては次回にします。

表記方法について

今回は一つのコンポーネントについてたくさんの プロパティを編集する場合があります。

その時に本記事では「プロパティ名:値, プロパティ 名:値 ・・・」という形式で表記します。

具体的には以下のようになります。

Text:"ブロック崩し",
Width:1048,
Height:233,
X:156,
Y:132,
Align:Center

また、一つのフィールドに大量にロジックを書く場合があります。

その時には以下のように表記します。

Clear(Blocks);
ForAll([1,2,3,4,5] As I_x,
    ForAll([1,2,3] As I_y,
        Collect(Blocks,{
            life:RoundUp(Rand()*3,0) ,
            num:I_y.Value + (I_x.Value-1)*3,
            x:Block_width*(I_x.Value-1)+Block_padding*I_x.Value,
            y:Block_height*(I_y.Value-1)+Block_padding*I_y.Value
            })
    )
);
Navigate(ゲーム画面);

必要なコンポーネントを作成する

今回最終的に用いるコンポーネントは以下のようになります。

いくつかピックアップしてみてみましょう。

ブロックギャラリー

ギャラリーは色々ありますが、今回は「空の垂直ギャラリー」を使用しています。

ゲームエリアコンテナーの中に入れておいた方が色々都合がいいと思います。

ブロック四角形

ギャラリーの唯一の要素として四角形アイコンを追加しています。

ギャラリーの要素としてコンポーネントを追加するには、ギャラリー左上に出てる鉛筆マークを押してから挿入するか、「挿入ペインで項目を追加する」から追加する必要があります。

ブロックを表示する

ブロックについての定義をする

アプリ全体で使う要素なのでAppのOnstartでグローバル変数に定義していまいます。

Set(Block_width,126);
Set(Block_height,50);
Set(Block_padding,16);

ブロックのコレクションを作る

ギャラリーに渡すためのコレクションを作成します。

どこでやってもいいのですが、今回はタイトル画面スクリーンのスタートボタンを押したときに作成することにします。

ついでにゲーム画面スクリーンに移動するとしてコードは以下のようになります。

Clear(Blocks);
ForAll([1,2,3,4,5] As I_x,
    ForAll([1,2,3] As I_y,
        Collect(Blocks,{
            life:RoundUp(Rand()*3,0) ,
            num:I_y.Value + (I_x.Value-1)*3,
            x:Block_width*(I_x.Value-1)+Block_padding*I_x.Value,
            y:Block_height*(I_y.Value-1)+Block_padding*I_y.Value
            })
    )
);
Navigate(ゲーム画面スクリーン);

5×3個のブロックを配置するとします。

縦横それぞれをForAll関数で回します。

ForAll関数内ではCollect関数を使ってBlocksにBlockを作るパラメータを追加しています。

life

ブロックの耐久値です。

Rand関数は0~1の値がランダムに返ってくるので3倍して切り上げることで1,2,3のどれかがでるようにしています。

num

一意識別のために使うわけではなく、ギャラリー上に配置する時に必要になります。

1から始まる整数の連番で定義してます。

ForAllは場合によって並列実行されるらしいですが、今回は(少なくとも試した限りでは)順次実行されていました。

x,y

事前に定義されたBlockの大きさと余白を使って座標を定義します。

今回は順番に整列させてるだけです。

ブロックギャラリーでブロック四角形を並べて表示する

ギャラリーは一つ一つのアイテムに独自の座標系を用いることでいい感じに並べてくれるのが魅力です。

しかし、今回は全部同じ座標系で厳密に並べたいのでギャラリーの機能を封印するような設定が必要です。

Items:Blocks,
TemplatePadding:0,
TemplateSize:0
Height:Block_height,
Width:Block_width,
X:ThisItem.x,
Y:ThisItem.y - ThisItem.num,
ThisItem.life>0

TemplatePadding と TemplateSize を0にすることで、限りなく小さく圧縮されたItemたちが上から並んでいるような形になります。

具体的には高さ1の要素として上から敷き詰められていきます。

なのでブロックのY座標についてはその分補正しています。

これで事前に用意した座標でブロックを並べることができました。

ブロック四角形に色を付ける

せっかくなので、ブロックの残りの耐久値がわかるように色を塗り分けてみましょう。

ブロック四角形のFillフィールドを以下のように書き換えてください。

Switch(ThisItem.life,
3,RGBA(56, 178, 96, 1),
2,RGBA(56, 96, 178, 1),
1,RGBA(178, 56, 96, 1)
)

ブロックの配置を変えてみる

ここまでの作業によってランダムに3色に塗り分けられたブロックが表示されているようになったはずです。

実際にタイトル画面スクリーンのスタートボタンを押して確認してみると以下のようになります。

せっかくなので、ちょっと配置を変えてみましょう。

Blockのパラメータを設定するところで、3列目と2行目を消してみます。

Clear(Blocks);
ForAll([1,2,4,5] As I_x,
    ForAll([1,3] As I_y,
~以下略~

実際に3列目と2行目が消えているのが確認できます。

ブロックの大きさを変えてみる

続いて、ブロックの大きさを変えてみましょう。

まずはブロックのサイズを定義しているAppのOnstartを変更します。

とりあえず全部半分にしてみました。

Set(Block_width,63);
Set(Block_height,25);
Set(Block_padding,8);

Onstartを変更した時は忘れずに実行しましょう。

続いてスタートボタンを再度編集します。

縦横が小さくなった分数を増やして10×5で並べてみます。

Clear(Blocks);
ForAll([1,2,3,4,5,6,7,8,9,10] As I_x,
    ForAll([1,2,3,4,5] As I_y,
~以下略~

実行するとこんな感じです。

まとめ

こんな感じでブロックを好きに並べ替えることができました。

段々ブロック崩しっぽくなってきたんじゃないでしょうか。

Power Apps の色んな要素を駆使して作っているので、中々ハイレベルになってきてしまった気がします。

Power Apps の可能性を探るという当初の目的的には良いのかも(?)

参考

わかれば簡単! #PowerApps のTemplateSize=0の手法 – Qiita