マイクロビットでゲーム

 今回はマイクロビットでリアルタイムゲームを作成します。マイクロビットにはゲームをサポートするスプライト機能が用意されていますが、今回はあらかじめ用意されているゲーム関係の機能は利用しません。  作成するゲームですが、表示されているLEDを全て消すまでの時間を競います。Aボタンを押すと表示されているLEDが一つずつ消えていきます。全部消えると、かかった時間が表示されます。  ゲームの制作は一気に完成させるのではなく、少しずつ作成し動作を確認するようにします。

・JavaScript用Microbitエディター
https://makecode.microbit.org/

Aボタンが押されたらLEDを消す

 Aボタンが押されたらLEDを消すだけのゲームですが、なるべくシンプルにするため使用する変数は2つだけにします。1つはLEDを消すための位置を示す変数です。もう1つはゲームクリアまでにかかった時間を計測する変数です。  まず、Aボタンが押されたらLEDを消す部分を作成します。最初に「変数」を0にしてLEDを全点灯させます。「LEDに表示」ブロックを配置すると全消灯になっているので、LED部分をクリックして赤くします。25個すべてのLEDを点灯させておきます。

  • 「変数」カテゴリをクリック「変数「変数」を「0」にする」ブロックを設置、「基本」カテゴリの「LEDに表示」ブロックを設置する

  • 「最初だけ」ブロックに図のようにあてはめ、「LEDに表示」ブロックのLEDをすべてクリックし点灯状態にする

 次にAボタンが押された時に処理を行います。「入力」ブロックにある「ボタン「A」が押された時」ブロックを配置します。

  • 「入力」カテゴリの「ボタン「A」が押されたとき」をクリック

  • 図のように配置される

 Aボタンが押されたら「変数」の値で示されるLEDを消灯します。「変数」の値と表示するXY座標の関係を示す式は以下のようになります。

X座標:「変数」を5で割った余り
Y座標:「変数」を5で割った値

 5はマイクロビットのLEDの縦横の数です。マイクロビットのLED数は横5×縦5なので、このような計算になります。このように計算した座標を消灯ブロックに設定します。消灯した後には「変数」の値に1を足します。  「変数」の値が24未満であれば該当する座標のLEDを消灯し、そうでない場合はゲームをクリアしたことになるのでCLEARのメッセージを表示します。  ここまでのブロックを組み立てると以下のようになります。

  • 「論理」カテゴリから「もし「真」なら でなければ」ブロック、「「0」<「0」」ブロックをクリック、「変数」カテゴリから「変数」ブロックをクリック。"もし~"の部分に「変数」をあてはめ、「変数<24」に数値を変更する。続いて"なら~"に部分「LED」カテゴリから「消灯 x0y0」をクリックし配置、「計算」カテゴリ「・・・さらに表示」をクリックし、「「0」÷「1」のあまり」ブロックと「計算」カテゴリの「「0」÷「0」」ブロックをクリック。「変数」ブロックを図のようにそれぞれ配置、数値を5に変更。さらに「変数」カテゴリから「変数「変数」を「1」だけ増やす」をクリックし消灯ブロックの下に配置する。"でなければ~"には「基本」カテゴリの「文字列を表示"「hello!」"」をクリックし、文字列"hello!"を"CLEAR"に変更する。

 この段階でもゲームとしては動作しますので、マイクロビットにプログラムを転送して動かしてみましょう。Aボタンを押すとLEDが1つずつ消えていくはずです。すべて消すとCLEARの文字が表示されます。

タイマーを追加する

 次にゲームクリアまでの時間を示すタイマーを追加します。タイマーはプログラムが動作している間、カウントする必要があります。これは図のようにタイマーの値を示す変数を「ずっと」のブロックに入れるだけです。タイマーの変数名は「タイマー」にしてあります。変数を追加するには「変数」カテゴリの変数を追加をクリックします。

  • 「変数」カテゴリの「変数を追加」

    「変数」カテゴリの「変数を追加」

  • 「ずっと」ブロックには、「変数」カテゴリから「変数「変数」を「1」だけ増やす」ブロックを設置、変数「変数」を~の部分を変数「タイマー」に変更する

    「ずっと」ブロックには、「変数」カテゴリから「変数「変数」を「1」だけ増やす」ブロックを設置、変数「変数」を~の部分を変数「タイマー」に変更する

 「ずっと」のブロック内で「タイマー」の値をカウントしていくと困った問題も発生します。それは、ゲームを開始していないのに「タイマー」の値がカウント(増えて)しまうことです。「タイマー」の値はゲーム開始時に0にしなければいけません。そこで図のようにAボタンが押された時に「変数」の値を調べてゲームが始まっていない場合は常に「タイマー」の値を「0」にするようにします。

  • 論理カテゴリの「もし「真」なら」ブロックを追加し、図のように「ボタンAが押されたとき~」に追加する。同じブロックで数値が違うだけのブロックが配置してあるので、ブロックを選択してコピー&ペーストでも追加できます。選択し「Delete」を押せばブロックを消すこともできます

 ゲームクリアしたら最後に「タイマー」の値を表示します。ここまで組み立てると以下のようなブロック構成になります。

  • 図のように配置します。末尾にある「数を表示「タイマー」」の部分も変更してありますので忘れないようにしてください

 せっかくなのでゲームの音楽、BGMを追加しましょう。音楽はバックグラウンドで再生されるのでゲーム開始時に「メロディを開始する」ブロックを追加します。流す音楽はお好みのものを設定してください。

  • 「音楽」カテゴリから「メロディを開始する~」を選択し図のように配置します

リプレイ機能の追加

 ここまででもゲームとしてプレイすることはできますが問題もあります。特に困るのがゲームをクリアした後に、もう一度プレイすることができないということです。もう一度プレイするにはマイクロビットの電源を入れ直さないといけません。これは、さすがに無理がありますので、Bボタンを押したらリプレイできるようにします。リプレイはマイクロビットをリセットすることで実現します。

 リセットは「高度なブロック」のカテゴリにあります。「制御」のカテゴリをクリックすると「リセット」というブロックがありますので、これを配置します。

 完成したプログラムは以下のようになります。ブロックとソースコードで示します。ブロックを配置するのが面倒な方は新規プロジェクト作成後に、コードをコピー&ペーストしてください。

  • Bボタンの動作を追加するために「入力」カテゴリから「ボタン「A」が押されたとき」をクリック

    Bボタンの動作を追加するために「入力」カテゴリから「ボタン「A」が押されたとき」をクリック

  • ボタン「A」を「B」に変更します

    ボタン「A」を「B」に変更します

  • 「高度なブロック」カテゴリから「リセット」をクリックします

    「高度なブロック」カテゴリから「リセット」をクリックします

  • 「ボタン「B」が押されたとき」ブロックに「リセット」をあてはめます

    「ボタン「B」が押されたとき」ブロックに「リセット」をあてはめます

 let タイマー = 0
 let 変数 = 0
 input.onButtonPressed(Button.A, () => {
     if (変数 == 0) {
         タイマー = 0
         music.beginMelody(music.builtInMelody(Melodies.Entertainer), MelodyOptions.Once)
     }
     if (変数 < 24) {
         led.unplot(変数 % 5, 変数 / 5)
         変数 += 1
     } else {
         basic.showNumber(タイマー)
     }
 })
 input.onButtonPressed(Button.B, () => {
     control.reset()
 })
 変数 = 0
 basic.showLeds(`
     # # # # #
     # # # # #
     # # # # #
     # # # # #
     # # # # #
     `)
 basic.forever(() => {
     タイマー += 1
 })

 あとはマイクロビットに転送して遊んでみましょう。

  • 「B」ボタンを押すと何度でもゲームを開始できます

  • Aボタンを押すと音楽とともにゲームがスタート

  • すべて消し終わるとタイマーが表示されます

なお、ゲームクリア後にAボタンを押してもタイマーの値が表示されます。クリア後には一度しか表示されないようにしてみるとよいでしょう。

 このゲームで使用したタイマーはゲーム内での時間(1ループ1カウント)なので実時間を計測して結果を表示するように改良してみましょう。実時間を求めるには「入力」のカテゴリ内にある「稼働時間(ミリ秒)」のブロックを使います。ゲーム開始時に変数に稼働時間を入れておき、ゲームクリア時に現在の稼働時間から開始時の稼働時間を引き算すれば実際にかかった時間を求めることができます。

 参考までにボタンAを押すと稼働時間が表示されるプログラムを示します。正解は次回に掲載しますのでチャレンジしてみてください。

 input.onButtonPressed(Button.A, () => {
     basic.showNumber(input.runningTime())
     basic.showLeds(`
         . . . . .
         . . . . .
         . . . . .
         . . . . .
         . . . . .
         `)
 })
 basic.forever(() => {

 })
著者 古籏一浩
プログラミングをベースにして面白そうなものはとりあえずやってみるというスタンス。複雑なものよりシンプルで楽しめるものが好み。
著者サイト:http://www.openspc2.org/