マイクロビットのゲームブロックでディスプレイの上から1秒ごとに移動しながら落下するスプライトを作ってみます。
最初だけブロック内で落下物のスプライトを用意して、ずっとブロック内でYに 1 だけ足した後、1秒待つことで1秒ごとに落下していくスプライトの完成です。
このスプライトは一番下まで到達した時に止まってしまいますので、
一番下に到達した時に一旦スプライトを削除して、再び一番上にスプライトを作成します。
このコードでは落下物スプライトの作成が二箇所ありますので、関数でまとめておきます。
応用で落下物が下に到達し再び一番上にスプライトを生成する度に少しずつ落下速度を速くしてみます。
最初だけブロック内に移動周期に関する変数を用意して、最初は1秒(1000ミリ秒)にしておきます。
一時停止のブロックに移動周期の変数を代入し、落下物のスプライトが削除される度に移動周期の値を50ミリ秒ずつ少なくしていきます。
このコードで落下速度は徐々に速くなります。
今回のコードをMicroPythonで書き換えてみます。
MakeCodeではずっとブロック内で落下速度の調整の為の一時停止ブロックを追加していますが、MicroPythonではずっとブロックに該当する
While True:
内で一時停止(sleep)を入れてしまうと、ボタンA等のイベントの設置ができなくなります。
回避策として、MicroPythonで経過時間の測定をしてみようで使用しましたrun_everyを使用してみます。
from microbit import *
falling_object = [2, 0]
def render():
global falling_object
coord = ""
for y in range(0, 5):
for x in range(0, 5):
if falling_object[0] == x and falling_object[1] == y:
coord += "9"
else:
coord += "0"
coord += ":"
img = Image(coord)
display.show(img)
# 点を表示後に次に点を表示する箇所を指定する
def update_falling_object():
global falling_object
falling_object[1] += 1
# 描写の関数と、スプライトの動きの関数は分けた方が可読性が上がる
run_every(render, s=1)
run_every(update_falling_object, s=1)
while True:
sleep(10)
※ 末尾にwhile True:を入れることで、run_everyで指定したコードが実行される前にプログラムが終了することを防ぎます
落下物のスプライトが一番下に到達した時のコード
from microbit import *
falling_object = [2, 0]
def render():
global falling_object
coord = ""
for y in range(0, 5):
for x in range(0, 5):
if falling_object[0] == x and falling_object[1] == y:
coord += "9"
else:
coord += "0"
coord += ":"
img = Image(coord)
display.show(img)
# 点を表示後に次に点を表示する箇所を指定する
def update_falling_object():
global falling_object
# 点が一番下に到達していた場合は、次回は一番上に表示する
if falling_object[1] == 4:
falling_object[1] = 0
else:
falling_object[1] += 1
run_every(render, s=1)
run_every(update_falling_object, s=1)
while True:
sleep(10)
落下速度を徐々に速くするコード
from microbit import *
falling_object = [2, 0]
ticks = 20
current_tick = 0
def render():
global falling_object
coord = ""
for y in range(0, 5):
for x in range(0, 5):
if falling_object[0] == x and falling_object[1] == y:
coord += "9"
else:
coord += "0"
coord += ":"
img = Image(coord)
display.show(img)
# 点を表示後に次に点を表示する箇所を指定する
def update_falling_object():
global falling_object, current_tick, ticks
current_tick += 1
if current_tick >= ticks:
current_tick = 0
# 点が一番下に到達していた場合は、次回は一番上に表示する
if falling_object[1] == 4:
falling_object[1] = 0
if ticks > 0:
ticks -= 1
else:
falling_object[1] += 1
run_every(render, ms=50)
run_every(update_falling_object, ms=50)
while True:
sleep(10)
※ run_everyでの実行間隔を1秒から50ミリ秒に変更して、render関数内で調整するように変更