【GW直前企画】プログラマーもScratchプログラミングを楽しもう!その1~ラケットゲーム~
小学生のプログラミング教育義務化に向けてか、Scratchが話題です。
Scratch - Imagine, Program, Share
Scratchを取り扱っている子ども向けTV番組もあるくらいです。
Why!?プログラミング [技術 小5~6・中]|NHK for School
普段、プログラミングに携わっているIT業界の人間でも、Scratchを知っておいて損はありません。
子どもにプログラミングについて聞かれたときに、「それ何?」とか、「あれ?」とならないようにしておきたいところです。(私の娘たちは、もう父親に何か聞く、という年齢ではなくなってしまいましたが)
そこで、GW直前企画と銘打って、本日より3日間、ScratchプログラミングのTipsを紹介していきます。
もうすぐGW、お子さまとScratchを楽しむ前に、ちょっと予習をしておきましょう。
Scratchは、手軽にプログラムが作れます。こんな風にブラウザ上でプログラムを組んで、すぐに実行して、動作が確認できます。
プログラミングは、ブロックを組み合わせて行いますが、組んだブロックはこれだけ。
Scratchはイベントドリブンです。
イベントを先頭に、そのイベントに対しての処理をブロックで組み上げるスタイルでプログラミングを行います。ブロックのひと纏まりがイベントハンドラということですね。
そして、このプログラムのことを「スクリプト」といいます。
この場合は、「緑の旗がクリックされた」というイベントが起点になってます。
「10歩進む」は「スプライト」と呼ばれるオブジェクト(この場合はネコ)を10ピクセル動かすブロックです。
画面の端まできたら反転させる処理も「もし端に着いたら、跳ね返る」だけ。
それを「ずっと」という繰り返しを意味するブロックの中に入れます。
アニメーションを表示するプログラムが実に簡単に記述できてしまいますね。
それならと、ボールをラケット(Paddle)で打ち返すゲームを作ってみました。
ボールをラケットで打ち返すブロックはこれだけです。
ボールは最初、45度の角度に設定され、10ピクセルずつ右上に向かって動き、上端に当たって、反転します。
ボールの角度を確認してみると、最初に反転したときは、135度になっているのが分かります。
この状態で、右端に当たると、反転して、
今度は、-135度になります。
これをラケットで打ち返すには、角度を時計回りに「90度回す」を使って、-45度にします。
逆に、135度で下がってきたボールは、角度を反時計周りに「90度回す」を使って、45度にします。
つまり、ボールの角度がマイナス(-135度)のときは、時計回りに90度、角度がプラス(135度)のときは、反時計回りに90度回せばよいわけです。
変数も作れるので、「点数」という変数を作り、点数を1増やすブロックを、ラケットに当たった時の処理に加えます。
ラケットを動かすのはもっと簡単です。
これをラケットのスプライトに記述すれば、マウスに合わせて、ラケットを左右に動かせます。
「ラケットのスプライトに記述すれば」と書きましたが、スクリプトは、このスプライト毎に記述します。
ボールを動かすには、ボールのスプライトのスクリプトを記述する領域で、ラケットを動かすには、ラケットのスプライトのスクリプトを記述する領域で、それぞれブロックを組みます。
Scratchは、マルチスレッドであり、複数のオブジェクトに対して記述されたイベントハンドラが並行して実行されます。
これで完成、と言いたいところですが、このままだと不具合が生じます。
ボールの横がラケットに当たった時、グニグニと妙な動きをしてしまうのです。
子どもが作るのであれば、これでもOKですが、プログラマーとしては、このような動きは許せません。
なぜ、こんな動きをしてしまうのか、考えましょう。
不具合は、ボールがラケットに当たり、向きを変えて、10ピクセル動いても、まだラケットの範囲内にいる場合に起こります。
これを防ぐには、ボールがラケットに触れないところに移動するくらいまで、向きを変える処理を止めておく必要があります。
普通のプログラミングであれば、ボールやラケットの座標を計算したり、フラグを用いて、処理をさらに分岐させるところですが、Scratchには合いません。
それをやろうとすると、ブロックが複雑になり過ぎてしまいます。
簡単なのは、ラケットに当たっていたら、次の判定まで、少し時間を空ける方法です。
そのためには、ボールを動かす処理と、判定して向きを変える処理とを別スレッドにする必要があります。つまり、ブロックを分けます。ブロックを分けないで、向きを変える処理を止めると、ボールも止まってしまいますからね。
赤いライン(Line)のスプライトを画面の下端に入れ、また別のスレッドで、そのスプライトに触れたら止まるようにすれば出来上がりです。
どうでしたか?
「ラケットで打ち返すだけでは物足りない」ですかね。
それでは、次回は、「ブロック崩し」に挑戦してみましょう。