ドロップの動き

ドロップスの移動処理は、発生時、スライド時、ステージクリア時の3つのタイミングで行われていますが、これらはすべて1箇所のロジックで賄っています。
大体以下のような感じ。

dim ek , fwe,fwe ; フィールドマップの色情報をクリア
wpoke eli	; 埋っている場所のカウントをクリア
repeat 123
  dup ez,ep(0,cnt)	; 種別
  dup ey,ez(1)	; 表示位置Y
  dup ex,ez(2)	; 表示位置X
  dup ew,ez(3)	; 移動カウンタ

  if ez { ; 種別が0でないなら
    c0=cnt\fw+1,cnt/fw+1	; 目的地(フィールドマップ上の位置)を算出
    if  nb { c1=20 :ew=20 }	; 面クリ処理中なら、画面外(上)への幕開け移動を強制
    if ew { ; 移動が終わっていないなら
      ey+=(460-c1*40-ey)/ew	; 現在の表示位置、目的地座標、移動カウンタ残を
      ex+=(60+c0*40-ex)/ew	; もとにして表示位置を変化させる。
      ew-			; 移動カウンタ残を減らす
    }else{	; 玉が静止状態(目的地に到達している)なら
      ek(c0,c1)=ez 	; フィールドマップに種別情報を転記
      zf+=(cnt=121) 	; 121番目の玉が静止ならGameOverフラグを加算
    }
    pos ex,ey:gcopy 2,ez*48	; 玉描画
    if eli < cnt {	; 埋っている場所が少ないなら配列を詰める
      ep(0,eli)=ez,ey,ex,20	; 種別、表示位置Y,Xを引き継ぐ。移動カウンタは20。
      lpoke ez	; 以前使っていた玉情報を破棄
    }
    eli+ ; 埋っている場所のカウントをUp
  }
loop

epは玉(ドロップス)情報を管理する2次元配列。種別、表示位置Y,表示位置X、移動カウンタ を持ちます。
2次元配列を配列要素を付けたまま使用するとAXサイズ的に不利なので、dupして扱います。
種別→ez、表示位置Y→ey、表示位置X→ex、移動カウンタ→ew
さて、この情報の中には移動量とか、移動先座標がありません。その代わり移動カウンタが用意されています。
スライド処理など玉の移動中、画面更新回数にして残り何ステップ分移動するべきかの回数を格納します。
つまり0ならその玉は静止しているという扱い。

  • 玉の移動描画の要

玉の移動を描画するには、ここから画面更新1回分の移動量を求める必要があります
まず、dup後に種別が0かどうかチェックします。0ならそこには玉がないので処理不要。
玉があるなら、c0=cnt\fw+1,cnt/fw+1 で、その玉が居るべき場所(移動中の目的地マスの座標)を計算します。例によって、c1はc0(1)をdupしたもの。
このゲームでは玉は左下隅をcnt=0とし、右方向に並ぶようになっています。
その段が埋ったら1段上の左端へ続いていきますが、基本的に順序は1次元として考えることができるので、順序を示すcntからマス座標の変換が簡単に行えます。
ここで+1しているのは、フィールド配列の外周対策でフィールドマップの外側に1マス分余裕を持たせているため、左隅下のマス座標が(1,1)となるからです。


次に、移動中か静止状態かをewの値でチェックし、移動中の場合には表示位置情報の更新行います。
表示位置を変化させる式の 460-c1*40 と 60+c0*40 は、目的地の画面座標を計算しています。
この値から現在位置を引いた差分をewで割ると画面更新1回分の移動量となるので、それを表示位置に加算します。
移動中はewは20からスタートして減算されていくので、最初の移動量は差分の1/20、次回の表示では1/20移動した後の1/19が移動量、その次では1/18です。これらは演算上の切捨てはありますがほぼ同じ移動量となります。
(最初の差分が200とすると1/20は10なので次回の差分は10減って190。これの1/19も10なので次回は更に10減って180)最後は差分の1/1=差分丸ごとで移動ですからきっちり目的地に移動します。

  • ドロップスのスライド処理

ループの最中は、フィールド左下隅から現在のcntまでに処理した玉の個数を、eli+でカウントしています。
この個数がcntとずれている場合は、ずれた分の空いているマス(種別=0)があるわけなので配列の内容を詰めます。
このとき移動カウンタが20になるので、新しい目的地に向かって移動していくことになります。

  • ドロップス発生時の動き

このスクリプトとは別のところで玉の発生をしています。発生は1表示ステップで最大1個です。
玉の種類は乱数。現在位置Yは画面外、Xは乱数、移動カウンタは20です。
新しい玉はフィールド上で埋っている玉の最後尾に並びますが、最後尾位置の検索はせず、フィールドで言うと、『ここまで埋るとゲームオーバーになってしまう場所(左上隅の上の段)』の右隣に決めうちで発生させます。
配列の内容を詰める処理で勝手に最後尾に変更されます。
ステージ最初にいっぱい玉が発生しますが、eliが規定数に達するまで表示ステップ毎に発生する処理が仕込まれており、これはステージ中ずっと有効です。

  • クリア処理

クリア時に玉が一斉に画面上部へ飛んでいく演出をやっています。
これは if nb { c1=20 :ew=20 } によって強制的に目的地Y位置と移動カウンタ残を設定することで実現。
後は勝手にやってくれるわけです。(nbは面クリ処理中インクリメントされていく変数)