ゲームブロックで落下するスプライトを作ろう


マイクロビットのゲームブロックでディスプレイの上から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)

	# 点を表示後に次に点を表示する箇所を指定する
	falling_object[1] += 1

run_every(render, s=1)

while True:
	sleep(100)

※ 末尾に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)

	# 点を表示後に次に点を表示する箇所を指定する
	# 点が一番下に到達していた場合は、次回は一番上に表示する
	if falling_object[1] == 4:
		falling_object[1] = 0
	else:
		falling_object[1] += 1

run_every(render, s=1)

while True:
	sleep(100)

落下速度を徐々に速くするコード

from microbit import *

falling_object = [2, 0]

ticks = 20
current_tick = 0

def render():
	global falling_object, current_tick, ticks

	current_tick += 1

	if current_tick >= ticks:
		current_tick = 0

		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)

		if falling_object[1] == 4:
			falling_object[1] = 0
			if ticks > 0:
				ticks -= 1
		else:
			falling_object[1] += 1

run_every(render, ms=50)

while True:
	sleep(100)

※ run_everyでの実行間隔を1秒から50ミリ秒に変更して、render関数内で調整するように変更

京都の東本願寺で開催されているプログラミング教室で講師をしています。
詳しくはTera schoolを御覧ください。
同じカテゴリーの記事
マインクラフト用ビジュアルエディタを開発しています。

詳しくはinunosinsi/mcws_blockly - githubをご覧ください。