箱入り娘 を作った後、この大きなスプライトで
15 パズル を作ってみると良い感じになるのでは?と作ってみました。
RUN すると、パズルを表示した後、
空いているところで 99⇢0 のカウントダウンをしながら動かしていきます。
0 になったところで操作できるようになりますので、
カーソルキー(または ジョイスティック 1)で
空いているところ(数字)を基準に操作して下さい。
(この操作は 15 パズル に同じ操作です)
動かすと数字が増えていきます。
元の状態に戻したところでプログラム終了です。
IchigoJam BASIC 版 も存在します。
100 R=RND(-TIME)
110 DEFINT A-Z
120 M=16
130 S=0
140 SCREEN 1,3
150 KEY OFF
160 DIM S$(16),P(16)
170 FOR I=1 TO 16
180 PUT SPRITE I,(((I-1) MOD 4)*32+64,INT((I-1)/4)*32+32),15,I
190 P(I)=I
200 NEXT I
210 FOR I=32*1 TO 32*16-1
220 READ S$
230 VPOKE &H3800+I,VAL("&H"+S$)
240 NEXT I
250 FOR I=99 TO 0 STEP -1
260 R=RND(1)*4+1
270 ON R GOSUB 610,630,650,670
280 IF M=T GOTO 260
290 PUT SPRITE T,,,16
300 PUT SPRITE M,,,P(T)
310 SWAP P(M),P(T)
320 M=T
330 B$=RIGHT$(STR$(I),2)
340 FOR J=0 TO 7
350 VPOKE &H3800+32*16+J+4,VPEEK(ASC(MID$(B$,1,1))*8+J)/2
360 VPOKE &H3800+32*16+J+20,VPEEK(ASC(MID$(B$,2,1))*8+J)/2
370 NEXT J
380 NEXT I
390 B$=RIGHT$(" "+STR$(S),4)
400 FOR J=0 TO 7
410 VPOKE &H3800+32*16+J,VPEEK(ASC(MID$(B$,1,1))*8+J)/2
420 VPOKE &H3800+32*16+J+16,VPEEK(ASC(MID$(B$,2,1))*8+J)/2
430 VPOKE &H3800+32*16+J+8,VPEEK(ASC(MID$(B$,3,1))*8+J)/2
440 VPOKE &H3800+32*16+J+24,VPEEK(ASC(MID$(B$,4,1))*8+J)/2
450 NEXT J
460 C=16
470 IF P(C)<>C GOTO 520
480 C=C-1
490 IF C>0 GOTO 470
500 IF INKEY$<>"" GOTO 500
510 END
520 K=STICK(0)+STICK(1)
530 ON K GOSUB 610,680,630,680,650,680,670
540 IF T=M GOTO 520
550 PUT SPRITE T,,,16
560 PUT SPRITE M,,,P(T)
570 SWAP P(M),P(T)
580 M=T
590 S=S+1
600 GOTO 390
610 T=M+(M>4)*4
620 RETURN
630 T=M-(M MOD 4>0)
640 RETURN
650 T=M-(M<13)*4
660 RETURN
670 T=M+(M MOD 4<>1)
680 RETURN
690 DATA 00,7F,7F,7F,7F,7F,7F,7F,7F,7F,7F,7F,7F,7F,7F,00
700 DATA 00,FE,FE,E6,E6,E6,E6,E6,E6,E6,E6,E6,E6,FE,FE,00
710 DATA 00,7F,7F,7E,7E,7F,7F,7E,7E,7E,7E,7E,7E,7F,7F,00
720 DATA 00,FE,FE,06,06,E6,E6,06,06,7E,7E,06,06,FE,FE,00
730 DATA 00,7F,7F,7E,7E,7F,7F,7E,7E,7F,7F,7E,7E,7F,7F,00
740 DATA 00,FE,FE,06,06,E6,E6,06,06,E6,E6,06,06,FE,FE,00
750 DATA 00,7F,7F,7E,7E,7E,7E,7E,7E,7F,7F,7F,7F,7F,7F,00
760 DATA 00,FE,FE,66,66,66,66,06,06,E6,E6,E6,E6,FE,FE,00
770 DATA 00,7F,7F,7E,7E,7E,7E,7E,7E,7F,7F,7E,7E,7F,7F,00
780 DATA 00,FE,FE,06,06,7E,7E,06,06,E6,E6,06,06,FE,FE,00
790 DATA 00,7F,7F,7E,7E,7E,7E,7E,7E,7E,7E,7E,7E,7F,7F,00
800 DATA 00,FE,FE,06,06,7E,7E,06,06,66,66,06,06,FE,FE,00
810 DATA 00,7F,7F,7E,7E,7F,7F,7F,7F,7F,7F,7F,7F,7F,7F,00
820 DATA 00,FE,FE,06,06,E6,E6,E6,E6,E6,E6,E6,E6,FE,FE,00
830 DATA 00,7F,7F,7E,7E,7E,7E,7E,7E,7E,7E,7E,7E,7F,7F,00
840 DATA 00,FE,FE,06,06,66,66,06,06,66,66,06,06,FE,FE,00
850 DATA 00,7F,7F,7E,7E,7E,7E,7E,7E,7F,7F,7E,7E,7F,7F,00
860 DATA 00,FE,FE,06,06,66,66,06,06,E6,E6,06,06,FE,FE,00
870 DATA 00,7F,7F,66,66,66,66,66,66,66,66,66,66,7F,7F,00
880 DATA 00,FE,FE,06,06,66,66,66,66,66,66,06,06,FE,FE,00
890 DATA 00,7F,7F,67,67,67,67,67,67,67,67,67,67,7F,7F,00
900 DATA 00,FE,FE,E6,E6,E6,E6,E6,E6,E6,E6,E6,E6,FE,FE,00
910 DATA 00,7F,7F,66,66,67,67,66,66,66,66,66,66,7F,7F,00
920 DATA 00,FE,FE,06,06,E6,E6,06,06,7E,7E,06,06,FE,FE,00
930 DATA 00,7F,7F,66,66,67,67,66,66,67,67,66,66,7F,7F,00
940 DATA 00,FE,FE,06,06,E6,E6,06,06,E6,E6,06,06,FE,FE,00
950 DATA 00,7F,7F,66,66,66,66,66,66,67,67,67,67,7F,7F,00
960 DATA 00,FE,FE,66,66,66,66,06,06,E6,E6,E6,E6,FE,FE,00
970 DATA 00,7F,7F,66,66,66,66,66,66,67,67,66,66,7F,7F,00
980 DATA 00,FE,FE,06,06,7E,7E,06,06,E6,E6,06,06,FE,FE,00
WebMSX では起動してから乱数を発生するタイミング(TIME の値)が
毎回同じになってしまうので、現在時刻の秒から乱数を生成しています。
(MSX1 では CLOCK-ID がないので除外しています)
101 IF PEEK(&H2D)=0 GOTO 10
102 GET TIME T$
103 R=VAL(RIGHT$(T$,2))
104 R=RND(-R)
170 FOR I=1 TO 16
180 PUT SPRITE I,(((I-1) MOD 4)*32+64,INT((I-1)/4)*32+32),15,I
190 P(I)=I
200 NEXT I
RUN して先にスプライトの表示位置を設定しています。
290 PUT SPRITE T,,,16
300 PUT SPRITE M,,,P(T)
550 PUT SPRITE T,,,16
560 PUT SPRITE M,,,P(T)
210 FOR I=32*1 TO 32*16-1
220 READ S$
230 VPOKE &H3800+I,VAL("&H"+S$)
240 NEXT I
通常スプライトは SPRITE$ を用いるのですが、
SCREEN 1~3 の場合、&H3800 からがスプライトの形状を入れている
スプライトパターン・ジェネレータテーブルとなっています。
&H3800 からパターン 0、パターン 1 と続いていきます(8x8・16x16 共に)
32*1~32*16-1 としているので、パターン 1~16 のスプライトを入れています。
330 B$=RIGHT$(STR$(I),2)
340 FOR J=0 TO 7
350 VPOKE &H3800+32*16+J+4,VPEEK(ASC(MID$(B$,1,1))*8+J)/2
360 VPOKE &H3800+32*16+J+20,VPEEK(ASC(MID$(B$,2,1))*8+J)/2
370 NEXT J
380 NEXT I
390 B$=RIGHT$(" "+STR$(S),4)
400 FOR J=0 TO 7
410 VPOKE &H3800+32*16+J,VPEEK(ASC(MID$(B$,1,1))*8+J)/2
420 VPOKE &H3800+32*16+J+16,VPEEK(ASC(MID$(B$,2,1))*8+J)/2
430 VPOKE &H3800+32*16+J+8,VPEEK(ASC(MID$(B$,3,1))*8+J)/2
440 VPOKE &H3800+32*16+J+24,VPEEK(ASC(MID$(B$,4,1))*8+J)/2
450 NEXT J
拡大表示にしているので、スプライトで数字を表示すれば拡大します。
せっかくなので、空いてるところに数字を表示するようにしました。
数字を文字列にして VPOKE でスプライトを入れています。
SCREEN 1 では VDP の番地は 0 番から VPOKE の 0 番なので、
単に キャラクターコード✕8 から 8 バイトで読み込めます。
(ここに書き込んで、キャラクターの変更もできます)
SPRITE$ だと面倒な処理も VPOKE なので最小限に処理できています。
ただし VPEEK・VPOKE で線画しているので、1~2 秒要しますが、
これが操作のウエイトになっていて、ちょうど良い感じになり、
数字が上から変化して表示されるのも新鮮です。
マシン語だと素早く転送して切り替えできるので、
実際に製品でスプライトを用いて文字表示を行っているものがあります。
(例えばカシオが出した エクゾイドZ のスコア等の上部表示)
410~440 で 4 文字表示しています。左上・右上・左下・右下の順ですが、
16x16 のスプライトは左上・左下・右上・右下 の順なので、ご注意下さい。