○ゲーム制作に便利な機能

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

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

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

○自機の移動

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

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

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

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

なお、このプログラムの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座標(横方向)の位置を決めます。

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

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

完成したらダウンロードボタンをクリックして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を入れておきます。

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

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

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

完成したプログラムですが、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)
})

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

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

画像提供:マイナビニュース