ゲーム制作に便利な機能

 マイクロビットは子供が喜ぶ機能が用意されています。それはゲーム制作に便利な機能です。その1つがスプライト機能です。通常マイクロビットでLEDの表示を行うと表示されているLEDの状態を気にしつつ点灯と消灯処理をしなければなりません。スプライト機能があれば、LEDの表示内容に関係なく任意の位置に表示することができます。自動的に消灯処理も行われます。なお、マイクロビットのスプライトは1×1サイズです。複雑な形状のものは扱えません。
 他にはスプライト同士の衝突判定やスコア加算、ゲームオーバー処理なども用意されています。マイクロビットでゲームを作ってくださいといわんばかりの機能です。  そこで、今回はマイクロビットで用意されているゲーム関連の機能を使って隕石避けゲームを作成してみます。上から落下してくる隕石を避けて進みます。自機は画面の一番下にありボタンAで左に移動、ボタンBで右に移動します。隕石にあたるとゲームオーバーとなります。

 ゲーム制作は一度に作るのではなく、少しずつ動作を確認しつつ作成します。

・JavaScript用のブロックエディタ
https://makecode.microbit.org/

自機の移動

 まず、自機の移動処理を作成します。自機のスプライトを扱うためには変数を作成します。ここでは「自機」という名前の変数を作成します。

  • 新規プロジェクトから「変数」ブロックの「変数を追加する」をクリック
  • 新規プロジェクトから「変数」ブロックの「変数を追加する」をクリック
  • 新規プロジェクトから「変数」ブロックの「変数を追加する」をクリック

  • 「New variable name:」ダイアログが表示されるので「自機」と入力します。「変数」カテゴリに「自機」変数が追加されます
  • 「New variable name:」ダイアログが表示されるので「自機」と入力します。「変数」カテゴリに「自機」変数が追加されます
  • 「New variable name:」ダイアログが表示されるので「自機」と入力します。「変数」カテゴリに「自機」変数が追加されます

次にスプライトを作成します。最初だけのブロックに「自機」の変数を入れます。次にカテゴリの「ゲーム」から「スプライトを作成 X:□ Y:□」ブロックを配置します。ブロックは「自機」の変数の値として入れます。

  • 「変数」ブロックから「変数「変数」を「0」にする」をクリック、「ゲーム」カテゴリから「スプライトを作成 X:「2」Y:「2」」を選び、図のように配置します
  • 「変数」ブロックから「変数「変数」を「0」にする」をクリック、「ゲーム」カテゴリから「スプライトを作成 X:「2」Y:「2」」を選び、図のように配置します
  • 「変数」ブロックから「変数「変数」を「0」にする」をクリック、「ゲーム」カテゴリから「スプライトを作成 X:「2」Y:「2」」を選び、図のように配置します

次にボタンが押されたら自機を移動させる処理を追加します。ボタンが押されたら処理するブロックを配置したら、その中に「スプライト「自機」を「-1」ドット進める」ブロックを入れます。ボタンAのブロックを作成したら、同様にボタンBのブロックも作成します。ボタンBの場合は1ドット進めるようにします。

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

  • 「ゲーム」カテゴリから「スプライト「変数」を「1」どっと進める」をクリック、図のように変数を「自機」に「1」を「-1」に変えて、「ボタン「A」が押されたとき」へ当てはめます
  • 「ゲーム」カテゴリから「スプライト「変数」を「1」どっと進める」をクリック、図のように変数を「自機」に「1」を「-1」に変えて、「ボタン「A」が押されたとき」へ当てはめます
  • 「ゲーム」カテゴリから「スプライト「変数」を「1」どっと進める」をクリック、図のように変数を「自機」に「1」を「-1」に変えて、「ボタン「A」が押されたとき」へ当てはめます

  • 同様に「ボタン「B」が押されたとき」を配置し、「ゲーム」カテゴリから「スプライト「変数」の「X」を「1」だけ増やす」をクリック。変数を「自機」に変えます

    同様に「ボタン「B」が押されたとき」を配置し、「ゲーム」カテゴリから「スプライト「変数」の「X」を「1」だけ増やす」をクリック。変数を「自機」に変えます

これでボタンを押すと自機が左右に移動します。ダウンロードボタンをクリックしてHEXファイルを作成したらマイクロビットに転送して動作を確認します。ボタンを押すと自機を示すLEDが動くはずです。

  • 自機にあたるLEDをA/Bボタンで左右に動かせるようになります

なお、このプログラムのJavaScriptコードは以下のようになります。ブロックを組み合わせるのが面倒な人は、このコードをコピー&ペーストしてください。

 let 自機: game.LedSprite = null
 input.onButtonPressed(Button.A, () => {
     自機.move(-1)
 })
 input.onButtonPressed(Button.B, () => {
     自機.change(LedSpriteProperty.X, 1)
 })
 自機 = game.createSprite(2, 4)
 basic.forever(() => {

 })

隕石を動かす

 次に隕石を動かします。衝突判定は後回しにして隕石が上から下に落下し、再度上からでてくる処理を作成します。隕石も自機と同じようにスプライトを作成します。その際、乱数を使ってX座標(横方向)の位置を決めます。

  • 先の手順同様に変数に「隕石」を追加し、「計算」カテゴリから「0~「4」の範囲の乱数」を選び、図のように新たなスプライトを追加します

    先の手順同様に変数に「隕石」を追加し、「計算」カテゴリから「0~「4」の範囲の乱数」を選び、図のように新たなスプライトを追加します

 次に隕石が下まで行った場合、再度一番上に移動させる処理を追加します。これはスプライトの座標を調べて一番下、つまりY座標が4なら、再度Y座標を0にしてX座標を0〜4までのランダムな値に設定します。

  • 「論理」カテゴリから「もし「真」なら」を選び、図のようにスプライトを「ずっと」ブロックに配置します

    「論理」カテゴリから「もし「真」なら」を選び、図のようにスプライトを「ずっと」ブロックに配置します

 あとは隕石のY座標を1つ増やす処理を加えます。このままでも動作しますが、実行するとあまりに速くてよくわかりません。そこで適度にウェイトを入れます。

  • 「ゲーム」カテゴリから「スプライト「変数」の「X」を「1」だけ増やす」を選び、変数を「隕石」に、「X」を「Y」に変更。「基本」カテゴリから「一時停止(ミリ秒)「100」」を配置します

    「ゲーム」カテゴリから「スプライト「変数」の「X」を「1」だけ増やす」を選び、変数を「隕石」に、「X」を「Y」に変更。「基本」カテゴリから「一時停止(ミリ秒)「100」」を配置します

完成したらダウンロードボタンをクリックしてHEXファイルを作成します。できあがったファイルをマイクロビットに転送して動作を確認しましょう。上から隕石が落下してくるはずです。また、ボタンを押すと自機が移動すればバッチリです。

  • 上からランダムに隕石が降ってくる機能が追加されます

なお、ここまでのJavaScriptコードは以下のようになります。

 let 隕石: game.LedSprite = null
 let 自機: game.LedSprite = null
 input.onButtonPressed(Button.A, () => {
     自機.move(-1)
 })
 input.onButtonPressed(Button.B, () => {
     自機.change(LedSpriteProperty.X, 1)
 })
 自機 = game.createSprite(2, 4)
 隕石 = game.createSprite(Math.random(5), 2)
 basic.forever(() => {
     if (隕石.get(LedSpriteProperty.Y) == 4) {
         隕石.set(LedSpriteProperty.Y, 0)
         隕石.set(LedSpriteProperty.X, Math.random(5))
     }
     隕石.change(LedSpriteProperty.Y, 1)
     basic.pause(100)
 })

衝突判定とスコア

 最後に衝突判定とゲームオーバーの処理を追加します。マイクロビットには自動的にスコアを加算するブロックがありますが、ここでは使用しません。これは、スコアのブロックを使うと衝突判定にひっかかってしまうのか、期待通りに動作しないためです。そこでスコアを加算する変数を用意します。

  • 再び「変数」カテゴリから「変数を追加する」をクリック、「スコア」と入力してスコア変数を追加します
  • 再び「変数」カテゴリから「変数を追加する」をクリック、「スコア」と入力してスコア変数を追加します
  • 再び「変数」カテゴリから「変数を追加する」をクリック、「スコア」と入力してスコア変数を追加します

  • 変数にスコアが追加されます。「変数「変数」を「0」にする」をクリックし、

    変数にスコアが追加されます。「変数「変数」を「0」にする」をクリックし、

スコアの変数を用意したら、最初に0を入れておきます。

  • 変数を「スコア」に変更し、「最初だけ」ブロックに当てはめます

    変数を「スコア」に変更し、「最初だけ」ブロックに当てはめます

このスコアですが、隕石を1つよけたら1点加算するようにします。そこで、隕石が一番下まで行った時にスコアを1つ増やすブロックを追加します。

  • 「変数」カテゴリから「変数「変数」を「0」だけ増やす」をクリックし、「変数」を「スコア」に変更し、図のように配置します|

    「変数」カテゴリから「変数「変数」を「0」だけ増やす」をクリックし、「変数」を「スコア」に変更し、図のように配置します

次に自機と隕石の衝突判定を行います。マイクロビットにはスプライト同士が衝突したかどうか調べるブロックが用意されています。論理のブロックと図のように組み合わせます。

  • 「論理」カテゴリから「もし「真」なら」を選び、その中に「ゲーム」カテゴリから「スプライト「変数」が他のスプライト「 」にさわっている?」を配置。図のように配置します。スプライトの最後の空白には、「変数」ブロックから変数隕石をクリックし当てはめます

    「論理」カテゴリから「もし「真」なら」を選び、その中に「ゲーム」カテゴリから「スプライト「変数」が他のスプライト「 」にさわっている?」を配置。図のように配置します。スプライトの最後の空白には、「変数」ブロックから変数隕石をクリックし当てはめます

 自機と隕石が衝突したらゲームオーバーなので、ゲームオーバーのブロックを入れます。なお、マイクロビットでのゲームオーバーの処理は自動的にアニメーションとメッセージ表示(GAME OVER文字の表示)とスコアの表示が行われます。スコアは「点数を設定する」ブロックに作成しておいた「スコア」の変数ブロックを入れます。このブロックの後に「ゲームオーバー」ブロックを入れれば完成です。

  • 「ゲーム」カテゴリから「点数を設定する「0」」をクリックし、0に変数「スコア」を設定、同じく「ゲーム」カテゴリから「ゲームオーバー」をクリックし、図のように「もし~なら」の「なら」のあとに当てはめます
  • 「ゲーム」カテゴリから「点数を設定する「0」」をクリックし、0に変数「スコア」を設定、同じく「ゲーム」カテゴリから「ゲームオーバー」をクリックし、図のように「もし~なら」の「なら」のあとに当てはめます
  • 「ゲーム」カテゴリから「点数を設定する「0」」をクリックし、0に変数「スコア」を設定、同じく「ゲーム」カテゴリから「ゲームオーバー」をクリックし、図のように「もし~なら」の「なら」のあとに当てはめます

完成したプログラムですが、JavaScriptコードでは以下のようになります。ブロックだと複雑な感じになりますが、コードはかなりすっきりとしたものになります。

 let スコア = 0
 let 隕石: game.LedSprite = null
 let 自機: game.LedSprite = null
 input.onButtonPressed(Button.A, () => {
     自機.move(-1)
 })
 input.onButtonPressed(Button.B, () => {
     自機.change(LedSpriteProperty.X, 1)
 })
 自機 = game.createSprite(2, 4)
 隕石 = game.createSprite(Math.random(5), 2)
 スコア = 0
 basic.forever(() => {
     if (隕石.get(LedSpriteProperty.Y) == 4) {
         隕石.set(LedSpriteProperty.Y, 0)
         隕石.set(LedSpriteProperty.X, Math.random(5))
         スコア += 1
     }
     隕石.change(LedSpriteProperty.Y, 1)
     if (自機.isTouching(隕石)) {
         game.setScore(スコア)
         game.gameOver()
     }
     basic.pause(100)
 })

あとはできあがったプログラムをマイクロビットに転送して遊んでみましょう。難しい場合はウェイトを大きくしてみるといいかもしれません。また、最初は隕石がゆっくりと落下し、次第に高速に落下するように改良してみるのもよいでしょう。

  • 上から降ってくる隕石をよけると点数が加算されます。衝突するとすべてのLEDが点灯し、スコアとGAMEOVERの文字が流れ続けます

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