マイクロビット用ジョイスティック

今回はマイクロビット用のジョイスティックを使って見ましょう。マイクロビット用のジョイスティックとしては以下のようなものがあります。

(1)Micro:bit BBC ゲームパッド拡張ボード

Amazon.co.jp内販売ページ
https://www.amazon.co.jp/gp/product/B07K7K1Y8J/

(2)Dolity Arduino BBC Micro:bit用 ジョイスティック

Amazon.co.jp内販売ページ
https://www.amazon.co.jp/gp/product/B07B9BGY3F/

 これらのジョイスティックは、それぞれ接続するピンが異なっているため、互換性がありません。また、(2)のジョイスティックは外部に基板を接続できますが、(1)のジョイスティックは外部基板を接続できません。
 (1)のジョイスティックは基板上に電池(バッテリー)があり、充電することができます。これにより外部電源なしで使うことができます。このためゲーム用途だけでなくロボットの制御コントローラーなどに使うこともできます。

 それでは、それぞれのジョイスティックを使ったプログラムを作ってみます。

Micro:bit BBC ゲームパッド拡張ボード
 まず、Micro:bit BBC ゲームパッド拡張ボードを使ってみましょう(以後、これもジョイスティックで呼称を統一)。このジョイスティックを使うには、最初に電池(バッテリー)を基板上に装着します。バッテリー駆動させないのであれば、装着しなくても構いません。バッテリーを装着したら充電します。ジョイスティックの基板にあるPower(電源)に接続します。LEDの点滅回数によって充電量が分かる仕組みになっています。

 なお、このジョイスティックにマイクロビットを接続した場合、マイクロビット側からも電源が供給されますが、バッテリーへの充電はできません。
 ジョイスティックのボタンスティックのピン番号(端子番号)は以下のようになっています。

 ボタンは押されると1から0になります。スティックデジタルまたはアナログ値で取得できます。
まず、ボタンが押されたらボタンの名前をマイクロビットのLEDに表示してみましょう。高度なブロックにある「入出力端子」のカテゴリクリックします。

デジタルで読み取る」ブロックがありますので、これを利用します。

「論理」のカテゴリにある「もしなら」のブロックを使って入力値を調べます。

ボタンが押されると0になるので、0になったらボタン名を表示します。これをA~F、Pボタンの数だけブロックを配置します。

 JavaScriptコードの場合は以下のようになります。

basic.forever(function () {
basic.clearScreen()
if (pins.digitalReadPin(DigitalPin.P5) == 0) {
basic.showString("A")
}
if (pins.digitalReadPin(DigitalPin.P11) == 0) {
basic.showString("B")
}
if (pins.digitalReadPin(DigitalPin.P15) == 0) {
basic.showString("C")
}
if (pins.digitalReadPin(DigitalPin.P14) == 0) {
basic.showString("D")
}
if (pins.digitalReadPin(DigitalPin.P13) == 0) {
basic.showString("E")
}
if (pins.digitalReadPin(DigitalPin.P12) == 0) {
basic.showString("F")
}
if (pins.digitalReadPin(DigitalPin.P8) == 0) {
basic.showString("P")
}
})

 プログラムダウンロードマイクロビットに転送して動作を確認します。ボタンを押すとボタンに対応した文字がマイクロビットのLEDに表示されます。

スティックの値を読み取る

 今度はスティックの値を読み取ってみましょう。スティックデジタルではなくアナログで取得することができます。この値は横方向(X)と縦方向(Y)で若干範囲が異なっています。若干の誤差はありますが、以下のような範囲になります。

実際にスティックの値を調べてみましょう。以下のプログラムスティックのX座標とY座標の値をマイクロビットのLEDに表示します。

 JavaScriptコードの場合は以下のようになります。

basic.forever(function () {
basic.showString(" X")
basic.showNumber(pins.analogReadPin(AnalogPin.P1))
basic.showString(" Y")
basic.showNumber(pins.analogReadPin(AnalogPin.P2))
basic.showString("#")
})

 プログラムダウンロードマイクロビットに転送して動作を確認します。スティックを動かすとX方向とY方向の値がマイクロビットのLEDに表示されます。

 次にスティックを動かしたらLED上のドットを動かしてみましょう。ドットを動かす場合はスプライト機能を使うと簡単です。スプライト機能は座標だけを指定すれば消去・表示処理を自動で行ってくれます。また、画面の端まで移動した際の処理もブロック1つ加えるだけです。論理ブロックを使わないのでプログラムもすっきりしたものになります。
 スティックの上下左右にあわせてドットを動かすプログラムは以下のようになります。

 JavaScriptコードの場合は以下のようになります。

let 自機: game.LedSprite = null
自機 = game.createSprite(2, 2)
basic.forever(function () {
if (pins.analogReadPin(AnalogPin.P1) < 300) {
自機.change(LedSpriteProperty.X, -1)
自機.ifOnEdgeBounce()
}
if (pins.analogReadPin(AnalogPin.P1) > 780) {
自機.change(LedSpriteProperty.X, 1)
自機.ifOnEdgeBounce()
}
if (pins.analogReadPin(AnalogPin.P2) > 700) {
自機.change(LedSpriteProperty.Y, -1)
自機.ifOnEdgeBounce()
}
if (pins.analogReadPin(AnalogPin.P2) < 380) {
自機.change(LedSpriteProperty.Y, 1)
自機.ifOnEdgeBounce()
}
})

 プログラムダウンロードマイクロビットに転送して動作を確認します。マイクロビットに表示されているLEDスティックに合わせて動きます。

○塗りつぶしゲーム

 せっかくのジョイスティックですから、簡単なゲームを作ってみましょう。ゲーム内容は簡単でスティックで自機(点)を動かしてマイクロビットの5×5のLEDを全部点灯させるだけです。要は25個のLEDを全部塗り潰せばゲームクリアということです。

 ゲームプログラムジョイスティック処理の部分は前のプログラムと同じです。異なるのはゲームの部分です。まず、塗り潰すLEDの情報を配列に入れることにします。
 なお、配列のどの部分がXY座標に対応しているかは以下の計算式で求めます。

自機のY座標を5で割り小数値を切り捨てた値 + 自機のX座標を5で割ったあまり

 ジョイスティックを動かしてLED部分を塗り潰したら、該当する配列要素を1にします。このため、配列は最初に0を入れておきます。LEDは25個あるので、25個分の0を入れます。JavaScriptコードだと横一列で見やすいのですが、ブロックエディタでは縦長になってしまい、結構画面の場所を取るので見にくいかもしれません。
 ジョイスティックで自機を移動させてLEDを点灯させたら、あとは全部塗り潰したかどうかの判定を行います。配列要素を順番に読み出していきます。1なら合計を1つ増やします。合計が25ならゲームクリアということなので「ゲームオーバーブロックを使ってゲームクリアゲームオーバー)時の処理を行います。このゲームオーバー時の処理はブロックを配置するだけでGAME OVERの文字とスコアの表示が自動的に行われます。
 あと、もう1つ処理しなければいけないことがあります。それは、塗り潰した部分のLEDを点灯させておくことです。これは配列内の値を読み出して1なら点灯するようにします。なお、消灯は自動的に行われるので点灯処理だけですみます。
 都合のいいことに点灯処理と全部塗り潰したかどうかの判定は同じ繰り返し処理を使うことができます。

 実際のプログラムは以下のようになります。

 JavaScriptコードの場合は以下のようになります。

let y = 0
let x = 0
let 合計 = 0
let 配列: number[] = []
let 自機: game.LedSprite = null
自機 = game.createSprite(2, 2)
配列 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
basic.forever(function () {
if (pins.analogReadPin(AnalogPin.P1) < 300) {
自機.change(LedSpriteProperty.X, -1)
自機.ifOnEdgeBounce()
}
if (pins.analogReadPin(AnalogPin.P1) > 780) {
自機.change(LedSpriteProperty.X, 1)
自機.ifOnEdgeBounce()
}
if (pins.analogReadPin(AnalogPin.P2) > 700) {
自機.change(LedSpriteProperty.Y, -1)
自機.ifOnEdgeBounce()
}
if (pins.analogReadPin(AnalogPin.P2) < 380) {
自機.change(LedSpriteProperty.Y, 1)
自機.ifOnEdgeBounce()
}
配列[自機.get(LedSpriteProperty.Y) * 5 + 自機.get(LedSpriteProperty.X)] = 1
合計 = 0
for (let counter = 0; counter 850) {
自機.change(LedSpriteProperty.Y, -1)
自機.ifOnEdgeBounce()
}
if (pins.analogReadPin(AnalogPin.P3) < 250) {
自機.change(LedSpriteProperty.Y, 1)
自機.ifOnEdgeBounce()
}
配列[自機.get(LedSpriteProperty.Y) * 5 + 自機.get(LedSpriteProperty.X)] = 1
合計 = 0
for (let counter = 0; counter
(古籏一浩)

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