フルカラーLEDのWS2812B×10個を使い、LED1個づつをボールに見立てたスカッシュゲームです
一番手前のLEDが光った時に、IchigoJamのタクトスイッチかキーボードのスペースキーを押して打ち返します
打ち損じや空振りをしたときは、ゲームオーバーとなりプログラムを終了します
10 ‘simpleSQUASH
30 CLV:W=20:Q=10:P=1
110 @MAIN
120 FOR J=0 TO Q*3:[J]=0:NEXT
130 [ABS(P)*3]=50
140 WS.LED Q
150 IF P==Q-1 BEEP30:P=1-Q
170 IF P!=0 P=P+1:WAIT W:GOTO@MAIN
180 IF BTN(SPACE) || BTN() GOTO@GAMEOVER
210 CLT
220 @HIT
230 IF BTN(SPACE) || BTN() BEEP5:P=1:GOTO@MAIN
240 IF TICK()<W GOTO@HIT
250 @GAMEOVER
260 BEEP 100,120
■変数の説明■
W ボールスピード(WAIT時間)
スピードを遅くしたい時は、値を大きくしてください
逆に早くしたいときは、値を小さくしてください
Q フルカラーLEDの個数
WS2812B基板やテープのLED個数を指定します
このプログラムでは10個のLEDを使います
最大は30個までです(IchigoJam配列の仕様制限です)
P 現在のボール(LED)の位置
ボールの点灯位置です
プログラム実行中は、値が-9から9まで変化していきます
詳細はプログラム説明の170行目を参照してください
[] 配列 WS2812LEDの色設定
1個目のLEDには、[0]、[1]、[2]、の各配列にG、R、B、の輝度が設定されます
■プログラムの説明■
30行目 CLV:W=20:Q=10:P=1
使用する変数の初期値および定数を設定します
▪️変数の説明▪️を参照してください
110行目 @MAINルーチン
ボールを打って帰ってくるまでを繰り返す、メインルーチンです
120行目 FOR J=0 TO Q*3:[J]=0:NEXT
すべての配列を0にします(全てのボール位置を消灯します)
なお、以下ようにプログラムを変更すると、ボールの軌跡を描くことができます
120 FOR J=0 TO Q*3 STEP3:[J]=[J]/2:NEXT
ただし、IchigoJamR以外は処理速度が遅いため、FOR命令にSTEP3を追加するとよいでしょう
添え字のチェックはしていませんので、配列制限を超えると、この120行目がエラーになりますので注意してください
130行目 [ABS(P)*3]=50
新しいボール位置の色と輝度を設定します
このプログラムでは、ボール色を緑の輝度50に設定しました
ボール色を赤にしたいときは、[ABS(P)*3+1]=50 にします
青にしたいときは、[ABS(P)*3+2]=50 にします
140行目 WS.LED Q
フルカーラーLEDを設定した値で点灯します
実際には、新しいボール位置のLEDが点灯されます
これを連続して実行すると、ボールが動いているように見えるのです
150行目 IF P==Q-1 BEEP30:P=1-Q
もしボールが壁の位置なら、ボールの反転処理を行います
このプログラムでは、P=9の時に、P=-9にします
170行目 IF P!=0 P=P+1:WAIT W:GOTO@MAINN
もしボールが打点位置でなければ(変数Pが0でなければ)、ボールを移動して@MAINへ飛びます
0ならば、次の180行目を実行します
ボール移動のアルゴリズムは、変数Pの正負を利用しています
正数なら、ボールは壁へ移動し、負数な跳ね返りの移動をします
150行目で壁を判断して負数にして壁から跳ね返らせます
ボール位置としての変数Pの値は、1,2,3,4,5,6,7,8,9,-8,-7,-6,-5,-4,-3,-2,-1,0
のように変化します
変数Pには-9が設定される場合があるのですが、ボール位置としては使われません
ボールの往復運動(LEDの位置)と変数Pの値の変化を知るために、
145 PRINT P:INPUT Z
のプログラムを追加して実行すると理解しやすいです
180行目 IF BTN(SPACE)||BTN() GOTO@GAMEOVER
この処理がないと、ボタンやキーボードを押し続けると打ち返しが成功してしまいます
不正対策のためにこの判定プログラムが必要なのです
210行目 CLT
ボール打ち返しの待ちの時間をリセットします
220行目 @HITルーチン
230行目 IF BTN(SPACE)||BTN() BEEP5:P=1:GOTO@MAIN
240行目 IF TICK()<W GOTO@HIT
打点判定をおこないます
ボールの移動時間内に、IchigoJamのタクトスイッチかキーボードのスペースキーが押されれば、@MAINへ飛びます
このとき、ボール位置の変数Pに1を入れて打ち返します
打ち損じたとき(時間オーバーしたとき)は、次の250行目を実行します
250行目 @GAMEOVERルーチン
260行目 BEEP 100,120
BEEP音を低く長く鳴らして、ゲームオーバー処理をします
■応用と拡張■
1.ボールを打つところから、ゲームスタートにする
@MAIN処理の前にカウントダウン処理を追加して、
30行目の変数P初期値をP=0に変更する
これでもカウントダウン後に、タクトスイッチ押打でゲームスタートする
2. 壁位置と打点位置を別の色で点灯する
壁を赤だとすると、LET[(Q-1)*3)],0,50,0
打点位置を青だとすると、LET[0],0,0,50
3.打ち返すごとに得点を入れる 最高得点者ランキングを表示する
得点用の変数を追加して、+1づつ足していく
4.打ち返すごとに、だんだんボールスピードを上げる
変数Wの値を小さくしていく
5.打ち返すごとに、だんだん壁が迫ってくるようにする
壁の位置を保持する変数を追加し、-1づつ引いていく
6.ボールの色を変える(8色)
応用例として、色設定サブルーチンをプログラムに追加すればできます
130 I=ASB(P):C=6:L=100:GSB@SET_WS.LED(I,C,L)

この教材は「Creative Commons — CC BY-SA 4.0」の下に提供されています。
