Power Apps で横スクロールアクションゲームを作る 記事まとめ
Power Apps で横スクロールアクションゲームを作る の記事一覧です。
上から順にやってみよう!
Power Appsで横スクロールアクションゲームを作る ジャンプ編
https://zezeze.hateblo.jp/entry/2019/12/25/053353
Power Apps で横スクロールアクションゲームを作る 横スク編
https://zezeze.hateblo.jp/entry/2020/02/15/090558
Power Apps で横スクロールアクションゲームを作る ステージ構成編
https://zezeze.hateblo.jp/entry/2020/02/15/092135
Power Apps で横スクロールアクションゲームを作る コイン取得編
https://zezeze.hateblo.jp/entry/2020/02/15/092429
Power Apps で横スクロールアクションゲームを作る Collection化編
https://zezeze.hateblo.jp/entry/2020/02/15/092520
全部できたら、カスタマイズしてみるのも勉強になりますよ!
コイン取得のSEをつけたり、BGMをつけたり、タイトル画面を着けたりゲームオーバーを作ったりしてみたり。スコアもつけてみたり。いろいろ試してみてください!
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 でいろいろやることの楽しさを伝えられていたら嬉しく思います。
Power Apps で横スクロールアクションゲームを作る コイン取得編
1年以上前に作ったゲームアプリですが、今更ながら作り方の解説記事を書いてみます。
↓昨年9月に行われた海外コミュニティ主催のPowerAppsゲーム作成コンペで優勝したアプリ
https://twitter.com/bothernpa/status/1045855585797722112
こんな感じの横スクロールアクションゲームを去年作成しました。
いくつかのセンテンスに分けて、作り方の解説記事を書いていきます。
今回はコイン取得をやっていきます。
コインを取得したら、コインが消えるようにします。
前提条件
ジャンプ編で作成した犬くんとの衝突判定を書いていきます。
犬くんがジャンプできるようにしておいてください。
手順
・コイン画像を設置
・CoinVisibleに設定する変数を初期化
・Visibleに変数を設定
・当たり判定処理を記述
・コインの分だけ量産
・StepImageとの相対位置を設定
・CoinImage.Yの設定
・CoinImage.Xの設定
コイン画像を設置
コイン画像をプレイヤーの上に設置します。
CoinVisibleに設定する変数を初期化
コインの表示非表示を切り替えるため、コインのVisibleに変数を指定したいので
設定用の変数を初期化しておきます。
コインを量産する場合は、それぞれのコインに変数が必要になります。
Screen.OnVisible
UpdateContext({CoinVisible:true});
Visibleに変数を設定
コインのVisibleに変数を設定して表示、非表示を切り替えられるようにします。
CoinImage.Visible
CoinVisible
当たり判定処理を記述
描画更新タイマーで当たり判定をします。
プレイヤーがコインにちょっとでもかぶってたら当たりという条件で、コインを非表示にしています。
Timer.OnTimerStart
If(
// 横方向の判定。コインにプレイヤーがかぶっていたら当たり。
CoinImage1.X <= PlayerImage_2.X + PlayerImage_2.Width && CoinImage1.X + CoinImage1.Width >= PlayerImage_2.X
&&
// 縦方向の判定。コインにプレイヤーがかぶっていたら当たり。
CoinImage1.Y <= PlayerImage_2.Y + PlayerImage_2.Width && CoinImage1.Y + CoinImage1.Width >= PlayerImage_2.Y
,
// 当たったら、コインを非表示にする。
UpdateContext({CoinVisible:false});
);
コインの分だけ量産
とりあえず1つだけ作って、原理を確認できました。
あとはこれを量産すれば、コインを並べることができます。
StageImageの数だけ量産しましょう。
CoinImage.Yの設定
StageImage.Yの相対位置で指定することができます。
CoinImage1- 9 で異なるので注意しましょう。
CoinImage.Y
StageImage1.Y - 200
CoinImage.Xの設定
StageImage.Xの相対位置で指定することができます。
CoinImage1- 9 で異なるので注意しましょう。
CoinImage.X
StageImage1.X
まとめ
手順ができたら、犬くんをジャンプさせてコインにぶつけてみましょう。
うまくいっていれば、コインが消えるはずです。
Power Apps で横スクロールアクションゲームを作る ステージ構成編
1年以上前に作ったゲームアプリですが、今更ながら作り方の解説記事を書いてみます。
↓昨年9月に行われた海外コミュニティ主催のPowerAppsゲーム作成コンペで優勝したアプリ
https://twitter.com/bothernpa/status/1045855585797722112
こんな感じの横スクロールアクションゲームを去年作成しました。
いくつかのセンテンスに分けて、作り方の解説記事を書いていきます。
今回はステージ構成を作っていきます。
ステージ画像を設置
やり方の原理や考え方は前回の横スクのものと変わりません。
ステージをスクロールさせて、見切れたら右に移動させて、という具合です。
Coin dogのステージがどうなっているかというと、こんな感じで9つ分の画像で構成されています。
この9つのイメージに対して、前回のような処理を書いていくイメージです。
詳細は前回乗せたのでざっくり手順を書くと
・ステージの基準点を初期化
・基準の画像のXに変数を設定
・スクロール量設定を初期化
・タイマーで基準点を減算
・ループに対応させる
・複数ステージに対応させる
上記手順でスクロールするステージを設置することができます。
前回の記事を参考にStageImageを設置していきましょう。
参考
StageImage2.X
// * 1の部分をいじることで、StageImage1-9に対応できます。
If(
(StageImage1.X + (StageImage1.Width * 1)) > App.Width ,
StageImage1.X +(StageImage1.Width * 1) - (App.Width +StageImage1.Width),
StageImage1.X +(StageImage1.Width * 1)
)
StageImage2.Y
// アプリの縦幅 - ((セル1つ分の幅) * セル数)
// セル数をいじることで、なんマス分の高さにするか設定できます。
App.Height - ((StageImage1.Width/2) * 1)
StageImage2.Height
StageImage1.Width * 2.5
StageImage2.Width
App.Width / 8
こんな感じで適当に設定してみます。
これで横スクロールするステージが作成できました。
ステージに乗る
次に、以前作った犬くんを持ってきまして、ステージに乗れるようにします。
移植しただけだと地面に潜り込んでしまいます。
地面はGroundYで設定していました。
このGroundYをStepImageの地面のYと合わせて上げるとうまくいくはず。
・Playerの中心点を変数化して保持する
・描画ごとにGroundYを更新する
この作戦で行きます。
Playerの中心点を変数化して保持する
まずは判定で使うため、PlayerImageの中心点を変数化します。
Screen.OnVislble
UpdateContext({PlayerCenterX:PlayerImage_1.X + (PlayerImage_1.Width/2)})
描画ごとにGroundYを更新する
次にPlayerImageの中心点の真下にあるStepImageを調べて、地面の位置を取得します。
例のごとく描画タイマーに書いていきます。
Timer.OnStart
If(StageImage1_1.X < PlayerCenterX && StageImage1_1.X + StageImage1_1.Width > PlayerCenterX,UpdateContext({GroundY:StageImage1_1.Y}));
If(StageImage2_1.X < PlayerCenterX && StageImage2_1.X + StageImage1_1.Width > PlayerCenterX,UpdateContext({GroundY:StageImage2_1.Y}));
…
If(StageImage9_1.X < PlayerCenterX && StageImage9_1.X + StageImage1_1.Width > PlayerCenterX,UpdateContext({GroundY:StageImage9_1.Y}));
ちょっと量が多いですね。
オプション:関数化して可読性を上げる
かさばる関数はコードの可読性も下がるので、メソッド化してしまいましょう。
Button.OnSelectに実装を記述し、必要なタイミングでSelect(Button)のように記述すると、関数呼び出しのように使うことができます。
実装を書いておくボタン:
M_SetCurrentGroundY.OnSelect
実装を呼び出すタイマー:
Timer.OnTimerStart
Select(SetCurrentGroundY);
このように実装を切り分けることで、呼び出し元の実装からは簡潔になり、全体の流れを把握しやすくなります。
まとめ
これで起伏のあるステージの構成と、ステージの起伏に合わせてプレイヤーを大地に立たせることができました。
だいぶ形になってきましたね。
長い処理を関数化してしまうのはうまく使うと非常に便利です。通常のアプリ作成時にも活用してみてください。
Power Apps で横スクロールアクションゲームを作る 横スク編
1年以上前に作ったゲームアプリですが、今更ながら作り方の解説記事を書いてみます。
↓昨年9月に行われた海外コミュニティ主催のPowerAppsゲーム作成コンペで優勝したアプリ
https://twitter.com/bothernpa/status/1045855585797722112
こんな感じの横スクロールアクションゲームを去年作成しました。
いくつかのセンテンスに分けて、作り方の解説記事を書いていきます。
今回は横スクロールを作っていきます。
横スクロールで使うコントロール、変数など
コントロール 2種類
・イメージ 数個(木やステージなど)
・タイマー(描画更新タイマー)
描画更新用のタイマーはジャンプのものを利用してもOKです。同一アプリで作る場合は、同じものを使用しましょう。ない場合はDuration = 50のタイマーを用意してもらえばOKです。
変数 2種類
・TreeBasePositionX 木の基準位置
・ScrollValue 描画毎のスクロール量
木の画像を設置
まず適当に木を置きます。イメージを設置して、木の画像を指定します。
コントロールの名前もTreeImageにしておきます。
TreeBasePositionXを初期化
次にTreeImage.Xに変数を指定します。
最初に変数の定義が必要なので、Screen.OnVisibleで初期化しておきます。
Screen.OnVisible
UpdateContext({TreeBasePositionX:500});
TreeImage.Xの設定
初期化して準備ができたら、TreeImage.Xに変数を指定します。
TreeImage.X
TreeBasePositionX
これで変数を増減させると木も移動するようになりました。
ScrollValueの初期化
次に、描画更新用タイマーでTreeBasePositionXの値に減算していきます。
描画毎に加算する値は固定値でもいいですが、わかりやすくするため変数化しておきます。
先程と同様Screen.OnVisibleで設定します。
Screen.OnVisible
UpdateContext({TreeBasePositionX:500,ScrollValue:10});
横スクロールさせる
スクロール量の初期化ができたら、描画タイマーでTreeBasePositionXに減算していきます。
Timer.OnTimerStart
UpdateContext({TreeBasePositionX:TreeBasePositionX - ScrollValue})
これで再生すると、木が横にスーッと移動していくはずです。
横スクロールをループさせる
上記で木が横スクロールしてくれるようになりました!完成!ではありません。
今のままだと移動して見切れたきり、一生帰ってきません。見切れたら反対側から帰ってきてもらいましょう。
いじるのは描画タイマーだけです。
Timer.OnTimerStartに下記の通り記述します。
Timer.OnTimerStart
If(TreeBasePositionX + TreeImage.Width < 0,UpdateContext({TreeBasePositionX:App.Width}))
これで、見切れたら右から出てきてくれるようになります。
複数を横スクロールさせる
ひとまず無事横スクロールさせることができました。やったね。
ですが、これを横スクロールさせたいオブジェクトに対して全部やってたらきついものがあります。
10本木があったら関数の量10倍ですからね。
同じ動きのものはそんな事せずにスクロールさせることができます。
Power Apps では、コントロールとの相対位置で座標指定することができるので、
TreeImageをコピーして、Xプロパティをこんな感じにすることで一緒にスクロールさせられます。
TreeImage2.X
TreeImage.X + TreeImage2.Width
ですが、このままだと見切れたときに消えちゃうので具合が良くないです。
少し改良しましょう。
If()を使ってTreeImage2が画面外にいかないようにします。
TreeImage2.X
If(
(TreeImage.X + TreeImage2.Width) > App.Width ,
TreeImage.X + TreeImage2.Width - (App.Width + TreeImage.Width),
TreeImage.X + TreeImage2.Width
)
基準にするイメージとの位置関係にもよりますが、概ねこんな感じで相対位置を指定することができます。
まとめ
これで横スクロール的なものをつくることができるようになりました。
今回は木を例に上げましたが、ステージも全く同様にスクロールさせることができます。
だいぶゲームっぽくなってきたんじゃないでしょうか。
ちなみに、こういうゲーム作るのとかだとなにがどうなってるかよくわからなくなりがちなので、コメントはしっかり入れるようにしましょう。