インベーダーの移動、攻撃を再現してみました。(改修版)
速度調整が必要なら、WAIT命令を実行してください。
また、マウスの左ボタンの押下でインベーダーを消滅できます。
!インベーダー・ゲーム
DEF V2W(x)=4*x !仮想画面の座標を物理画面の座標へ
DEF W2V(x)=INT(x/4) !その逆
PICTURE DOT !物理画面にドットを表示する
PLOT AREA: -2,-2; 2,-2; 2,2; -2,2 !4x4
END PICTURE
LET vx=180 !仮想画面の大きさ 150×180ドット
LET vy=150
SET bitmap SIZE V2W(vx)+1,V2W(vy)+1 !物理画面の大きさ
SET WINDOW 0,V2W(vx),V2W(vy),0 !スクリーン座標
RANDOMIZE
!------------------------------ 弾
DATA "* " !コマ1 弾1
DATA " *"
DATA "* "
DATA " *" !コマ2
DATA "* "
DATA " *"
DIM bm$(1,2) !弾 3×2ドット
CALL ReadPattern(1,3, bm$)
LET NumOfBeam=5 !弾 最大数5
DIM BM(NumOfBeam,3)
MAT BM=(-1)*CON
!------------------------------ インベーダー
LET m=8 !m×nドット
LET n=11
DATA "** **" !コマ1 機体0
DATA "* *"
DATA " "
DATA " "
DATA " "
DATA " "
DATA "* *"
DATA "** **"
DATA " " !コマ2
DATA "* * * *"
DATA " * * * * "
DATA " * * "
DATA "** **"
DATA " * * "
DATA " * * * * "
DATA "* * * *"
DATA " * * " !コマ1 機体1
DATA "* * * *"
DATA "* ******* *"
DATA "*** *** ***"
DATA "***********"
DATA " ********* "
DATA " * * "
DATA " * * "
DATA " * * " !コマ2
DATA " * * "
DATA " ******* "
DATA " ** *** ** "
DATA "***********"
DATA "* ******* *"
DATA "* * * *"
DATA " ** ** "
DATA " *** " !コマ1 機体2
DATA " ***** "
DATA " ******* "
DATA " ** *** ** "
DATA " ********* "
DATA " * * "
DATA " * * * * "
DATA " * * * * "
DATA " *** " !コマ2
DATA " ***** "
DATA " ******* "
DATA " ** *** ** "
DATA " ********* "
DATA " * *** * "
DATA " * * "
DATA " * * "
DATA " " !コマ1 機体3
DATA " *** "
DATA " ********* "
DATA "** *** **"
DATA "***********"
DATA " ***** "
DATA " ** * ** "
DATA "** **"
DATA " " !コマ2
DATA " *** "
DATA " ********* "
DATA "** *** **"
DATA "***********"
DATA " ** ** "
DATA " * * "
DATA " * * "
DIM ptn$(4,2) !パターン(1機×2コマ)で読み込む
CALL ReadPattern(4,m, ptn$)
SUB ReadPattern(n,l, ptn$(,))
FOR k=1 TO n !各機体
FOR j=1 TO 2 !各コマ
LET v$=""
FOR i=1 TO l
READ s$
LET v$=v$&s$
NEXT i
LET ptn$(k,j)=v$ !登録する
NEXT j
NEXT k
END SUB
!------------------------------ 編隊
LET p=6 !p×q
LET q=8
DIM F(p+1,q) !0以上:生存フラグ、パターン番号
MAT F=ZER
DATA 4, 4, 4, 4, 4, 4, 4, 4 !パターン番号 ※偶数
DATA 4, 4, 4, 4, 4, 4, 4, 4
DATA 6, 6, 6, 6, 6, 6, 6, 6
DATA 6, 6, 6, 6, 6, 6, 6, 6
DATA 2, 2, 2, 2, 2, 2, 2, 2
DATA 2, 2, 2, 2, 2, 2, 2, 2
DATA 6, 6, 6, 6, 6, 6, 6, 6 !先頭の番号
MAT READ F
LET ox=n+2 !機体の間隔
LET oy=m+2
LET lx=vx-ox*q !編隊の左上位置
LET ly=4
PICTURE BLOCK(v$,m,n) !インベーダーなどを位置(0,0)-(n,m)に表示する
FOR i=0 TO m-1 !m×nドット
FOR j=0 TO n-1
LET k=i*n+j+1
IF v$(k:k)<>" " THEN DRAW DOT WITH SHIFT(V2W(j),V2W(i))
NEXT j
NEXT i
END PICTURE
LET DX=-1 !移動方向
LET FLG=0 !機体の動作
LET Invaded=0 !侵略状況
DO !ゲームループ
!------------------------------ 当り判定(仮)
MOUSE POLL mx,my,left,right !マウスの状態を得る
IF left=1 THEN !左ボタン押下なら
LET x=W2V(mx)-lx !編隊の領域内なら
LET y=W2V(my)-ly
IF x<0 OR x>=ox*q OR y<0 OR y>=oy*p THEN
ELSE
LET xx=MOD(x,ox) !機体内なら
LET yy=MOD(y,oy)
IF xx<n AND yy<m THEN
LET xx=INT(x/ox)+1 !該当する機体を爆発→消滅する
LET yy=INT(y/oy)+1
IF F(yy,xx)>=2 THEN LET F(yy,xx)=1
END IF
END IF
END IF
!------------------------------ 描画処理毎(フレームを表示する)
SET DRAW mode hidden !ちらつき防止開始
CLEAR
LET CntOfEnemy=0
FOR x=1 TO q !インベーダー群を表示する
IF F(p+1,x)>0 THEN !この列に機体が存在するなら
LET xx=lx+ox*(x-1)
LET F(p+1,x)=0
FOR y=1 TO p
LET ptn=F(y,x) !生存なら
IF ptn>=0 THEN
LET idx=INT(ptn/2) !パターンを選択する
LET koma=MOD(ptn,2)
DRAW BLOCK(ptn$(idx+1,koma+1),m,n) WITH SHIFT(V2W(xx),V2W(ly+oy*(y-1)))
IF ptn=1 THEN
LET F(y,x)=-1 !爆発→消滅
ELSE
LET F(y,x)=MOD(ptn+1,2)+idx*2 !ぱたぱたアニメーション
LET F(p+1,x)=y !先頭の番号を更新する
IF ly+oy*(y-1)>vy*2/3 THEN LET Invaded=1 !侵略したなら
END IF
LET CntOfEnemy=CntOfEnemy+1 !機体の数
END IF
NEXT y
IF F(p+1,x)>0 THEN !この列に機体があれば
IF FLG=0 THEN !折り返しを確認する
IF xx<=0 OR xx+n>=vx THEN LET FLG=1 !左端、右端なら
END IF
IF RND<0.1 THEN !弾を発射する
FOR y=1 TO NumOfBeam !未発射を探す
IF BM(y,3)<0 THEN
LET BM(y,1)=xx+INT(n/2)
LET BM(y,2)=ly+oy*(F(p+1,x)-1)+INT(m/2)
LET BM(y,3)=0 !使用中
EXIT FOR !1列に1つずつ
END IF
NEXT y
END IF
END IF
END IF
NEXT x
FOR y=1 TO NumOfBeam !弾を表示する
LET ptn=BM(y,3)
IF ptn>=0 THEN !使用中なら
DRAW BLOCK(bm$(1,ptn+1),3,2) WITH SHIFT(V2W(BM(y,1)),V2W(BM(y,2)))
LET BM(y,3)=MOD(ptn+1,2) !ぱたぱたアニメーション
END IF
NEXT y
SET DRAW mode explicit !ちらつき防止終了
!------------------------------ 移動処理(次のフレームへ)
SELECT CASE FLG !インベーダーを移動させる
CASE 0
LET lx=lx+DX !横へ移動させる
CASE 1
LET ly=ly+2 !折り返しの動作(降下させる)
LET FLG=2
CASE ELSE
LET DX=-DX !降下後、1つ離す
LET lx=lx+DX
LET FLG=0
END SELECT
FOR i=1 TO NumOfBeam !弾を移動させる
IF BM(i,3)>=0 THEN !使用中なら
LET BM(i,2)=BM(i,2)+3 !降下させる
IF BM(i,2)>vy THEN LET BM(i,3)=-1 !下端なら
END IF
NEXT i
!!!WAIT DELAY 0.3
LOOP UNTIL CntOfEnemy=0 OR Invaded=1 !機体全滅まで
END