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コントロール、ステージの高さを表すStageY、CoinImageコントロール、コインの表示設定値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});
);
まとめ
以上で一通り完成になります。
ちゃんと分かる記事になっているか不安もあるのですが、後ほど完成形のアプリをアップする予定です。記事がわかりにくい方は完成形を見ながらやってみましょう。
余力のある方は処理の高速化に挑戦してみるのもいいと思います。
LookUp()で相対位置を指定しているところはLast(FirstN())にしたほうが早そうな気がしてます。
全然余裕という方は、一部説明していない機能もあります。是非ご自身で挑戦してみてください。
もちろんカスタマイズ、拡張していってもいいです。
面白いものができたらぜひ Twitter で #PowerApps #JPAUG 等のタグでツイートしてください!僕が喜びます。
この記事でPower Apps でいろいろやることの楽しさを伝えられていたら嬉しく思います。