Power Appsの使い方

Power AppsとPower Automateの使い方やできることがわかるブログを目指しています。

Power Apps で横スクロールアクションゲームを作る Collection化編

1年以上前に作ったゲームアプリですが、今更ながら作り方の解説記事を書いてみます。

 

↓昨年9月に行われた海外コミュニティ主催のPowerAppsゲーム作成コンペで優勝したアプリ

https://twitter.com/bothernpa/status/1045855585797722112

 

こんな感じの横スクロールアクションゲームを去年作成しました。

いくつかのセンテンスに分けて、作り方の解説記事を書いていきます。

 

前回まででとりあえず横スクロール的なものを作成することができました。

 

ただ、今の所固定のステージをループしているだけです。

もう少し手を加えてコレクションからステージをロードするようにしましょう。

ちょっと難易度が上がるのでがんばってください。

 

基本的な考え方は以前と同様なので、細かいところは説明しません。

自身で読み取ってみてください。そういうこともいい勉強になると思います。

 

手順

・ステージ読み込みコレクションMapsを初期化

・ステージ設定コレクションStageControlsを初期化

LoadingIDを初期化

CellLengthを初期化 

StageImage.Y を変更
Coin.Visible を変更

・コイン当たり判定改修

GroundYの取得処理を改修

・ステージロード処理を追加

 

前提条件

以前までのステップをすべて完了している事が前提です。

 

ステージ読み込みコレクションMapsを初期化

ステージのMAP設定をコレクションに入れておきます。

LookUpで使うIDと、セルの高さを表すCellHeightを設定します。

※もっとたくさん作成しないとすぐステージが終わってしまうので、ID:100くらい入れといたほうがいいです。エクセル使うと量産が楽。

 

Screen.OnVisible

ClearCollect(Maps,

{ID:1,CellHeight:1},

{ID:2,CellHeight:1},

{ID:3,CellHeight:2},

{ID:4,CellHeight:2},

{ID:5,CellHeight:1},

{ID:6,CellHeight:1},

{ID:7,CellHeight:2},

{ID:8,CellHeight:1},

{ID:9,CellHeight:2},

{ID:10,CellHeight:1},

{ID:11,CellHeight:1},

{ID:12,CellHeight:2},

{ID:13,CellHeight:1},

{ID:14,CellHeight:2},

{ID:15,CellHeight:3},

{ID:16,CellHeight:4},

{ID:17,CellHeight:3},

{ID:18,CellHeight:1},

{ID:19,CellHeight:1},

{ID:20,CellHeight:2});

 

ステージ設定コレクションStageControlsを初期化

Stage1 - 9の設定値をコレクションに入れておきます。

LookUpで使うIDと、StageImageコントロール、ステージの高さを表すStageYCoinImageコントロール、コインの表示設定値CoinVisibleを設定します。

 

Screen.OnVisible

ClearCollect(StageControls,

{ID:1,StageImage:StageImage1_2,StageY:App.Height - (CellLength * LookUp(Maps,ID = 1,CellHeight)),CoinImage:CoinImage1_1,CoinVisible:true},

{ID:2,StageImage:StageImage2_2,StageY:App.Height - (CellLength * LookUp(Maps,ID = 2,CellHeight)),CoinImage:CoinImage1_2,CoinVisible:true},

{ID:3,StageImage:StageImage3_2,StageY:App.Height - (CellLength * LookUp(Maps,ID = 3,CellHeight)),CoinImage:CoinImage1_3,CoinVisible:true},

{ID:4,StageImage:StageImage4_2,StageY:App.Height - (CellLength * LookUp(Maps,ID = 4,CellHeight)),CoinImage:CoinImage1_4,CoinVisible:true},

{ID:5,StageImage:StageImage5_2,StageY:App.Height - (CellLength * LookUp(Maps,ID = 5,CellHeight)),CoinImage:CoinImage1_5,CoinVisible:true},

{ID:6,StageImage:StageImage6_2,StageY:App.Height - (CellLength * LookUp(Maps,ID = 6,CellHeight)),CoinImage:CoinImage1_6,CoinVisible:true},

{ID:7,StageImage:StageImage7_2,StageY:App.Height - (CellLength * LookUp(Maps,ID = 7,CellHeight)),CoinImage:CoinImage1_7,CoinVisible:true},

{ID:8,StageImage:StageImage8_2,StageY:App.Height - (CellLength * LookUp(Maps,ID = 8,CellHeight)),CoinImage:CoinImage1_8,CoinVisible:true},

{ID:9,StageImage:StageImage9_2,StageY:App.Height - (CellLength * LookUp(Maps,ID = 9,CellHeight)),CoinImage:CoinImage1_9,CoinVisible:true}

);

 

LoadingIDを初期化

ステージロード的な処理をするための、LoadingIDを初期化します。

LoadingIDをキーにMapsからLookUp()したりします。

最初の設定値は9にしておきます。

 

Screen.OnVisible

UpdateContext({LoadingID:9});

 

CellLengthを初期化

視認性向上と負荷軽減目的でセル1つ分の大きさを変数に入れておきます。

 

Screen.OnVisible

UpdateContext({CellLength:StageImage1_2.Width/2});

 

StageImage.Y を変更

StageImage.Yの設定をコレクションに対応した形に変更します。

StageImage1- 9 でIDが異なるので注意しましょう。

 

例:

StageImage.Y

LookUp(StageControls,ID = 1,StageY)


Coin.Visible
を変更

CoinImage.Visibleの設定をコレクションに対応した形に変更します。

StageImage1- 9 IDが異なるので注意しましょう。

 

例:

CoinImage.Visible

LookUp(StageControls,ID = 1,CoinVisible)

 

コイン当たり判定変更

コインの当たり判定をコレクションに対応したものに変更します。

 

Timer.OnStart

Patch(StageControls,

    LookUp(

        StageControls,

        // 横方向の判定。

        CoinImage.X  <= PlayerCenterX && CoinImage.X + CoinImage.Width >= PlayerCenterX

        &&

        // 縦方向の判定。

        CoinImage.Y <= PlayerImage_3.Y + PlayerImage_3.Width && CoinImage.Y + CoinImage.Width >= PlayerImage_3.Y 

     ),

     // Coinを非表示にする

     {CoinVisible:false}

 );

 

GroundYの取得処理を改修

GroundYの更新処理をコレクションに対応したものに変更します。

処理が1行で済むため、関数化するメリットは少なくなります。処理も軽くなります。

 

Timer.OnStart

UpdateContext({GroundY:LookUp(StageControls,StageImage.X < PlayerCenterX && StageImage.X + StageImage.Width > PlayerCenterX,StageImage.Y)});

 

ステージロード処理を追加

描画更新タイマーにステージロード的な処理を追加します。

今までの処理の一番下に追加します。

 

Timer.OnStart

// ステージロード仕様のための実装

If(

    // 右に移動したステージがあるなら

    !IsBlank(LookUp(StageControls,StageImage.X >= App.Width - 9)),

    // LoadingIDを更新

    UpdateContext({LoadingID:LoadingID + 1});

    // LoadingCellHeightを更新

    UpdateContext({LoadingCellHeight:LookUp(Maps,ID = LoadingID,CellHeight)});

    // 読み込んだステージの高さに設定。コインの表示値も初期化。

    Patch(StageControls,LookUp(StageControls,StageImage.X >= App.Width - 9),{StageY:App.Height - (CellLength * LoadingCellHeight),CoinVisible:true});

);

 

9 
フ ァ イ ル ホ - ム 
目 デ - タ ソ - ス 
OnVisible 
ツ リ - ビ ュ - 
刄 検 索 
App 
挿 入 
ヒ ュ - 
メ デ ィ ア 
ア ク シ ョ ン 
コ レ ク シ ョ ン 
圃 変 数 噬 詳 細 設 定 
、 ノ UpdateContext({StageBasePositionX:ø,ScroIIVaIue:IØ}), 
Test - 横 ス ク ロ - ル ア ク シ ョ ン - 保 存 済 み ( 発 行 取 り 消 し 済 み ) 
ジ ャ ン プ 
フ 
5 ( reen コ レ ク シ ョ ン 化 
プ ロ バ テ ィ 詳 篭 設 定 
フ ィ ル 
の 亘 像 
亘 像 の 仁 匿 
ぐ 
只 ◆ 
〉 [ コ 5 [ en ジ ャ ン プ 第 
〉 ー コ 立 en 盲 ス ク 編 
〉 ー コ 立 en ス テ - ジ 成 編 
〉 [ コ 立 en ス テ - ジ 成 編 2 
〉 ー コ 立 en 〕 イ ン 取 得 編 
v [ コ 5 び een コ レ ク シ ョ ン 化 
」 CoinGroup 
」 ump3utton_1 
Playerlmage_3 
SteplmageGroup_1 
の TimerI_5 
ロ 立 en コ レ ク シ ョ ン …

 

まとめ

以上で一通り完成になります。

ちゃんと分かる記事になっているか不安もあるのですが、後ほど完成形のアプリをアップする予定です。記事がわかりにくい方は完成形を見ながらやってみましょう。

 

余力のある方は処理の高速化に挑戦してみるのもいいと思います。

LookUp()で相対位置を指定しているところはLast(FirstN())にしたほうが早そうな気がしてます。

 

全然余裕という方は、一部説明していない機能もあります。是非ご自身で挑戦してみてください。

もちろんカスタマイズ、拡張していってもいいです。

 

面白いものができたらぜひ Twitter #PowerApps #JPAUG 等のタグでツイートしてください!僕が喜びます。

この記事でPower Apps でいろいろやることの楽しさを伝えられていたら嬉しく思います。

Power Apps / Power Automate の開発技術支援サービスや1日トレーニングコースを提供しています。

Power Apps や Power Automateに関する仕事のご依頼は下記ページからお問い合わせください。
ZEE CitizenDevSupport