NSDefSpline / NSSpline を使ってなめらかにホーミング
nslua.dllで使えるNSDefSplineとNSSplineは、それぞれスプライン補間曲線を作成する関数と実際の補間値を取得する命令である。
これを使えば、指定した三つ以上の点を通るなめらかな曲線を描くことができる。
例えば、画面上の点(80, 440)を出発し、25フレーム目で(80, 40)を通過、50フレーム目で(560, 440)に到着、終了とする曲線を考えてみる。
まずは、これを表にしてみる。
値 | … | … | NSDefSplineに与えるテーブル | |||
---|---|---|---|---|---|---|
frame | 0 | … | 25 | … | 50 | {0, 25, 50} |
x | 80 | … | 80 | … | 560 | {80, 80, 560} |
y | 440 | … | 40 | … | 440 | {440, 40, 440} |
定義
この曲線を定義するには、NSDefSplineを2回使う。
NSDefSpline(0, {0, 25, 50}, {80, 80, 560}) -- 第一引数は0〜99までのどれかを任意。第二引数はframe、第三引数はxを与える。 NSDefSpline(1, {0, 25, 50}, {440, 40, 440}) -- 第一引数は0〜99までのどれかを任意。第二引数はframe、第三引数はyを与える。 -- 第一引数はかぶらないこと。 NSExec("luasub spline") function NSCOM_spline() local frame = NSPopInt() NSPopComma() local retx = NSPopIntRef() NSPopComma() local rety = NSPopIntRef() NSSetIntValue(retx, NSSpline(0, frame)) NSSetIntValue(rety, NSSpline(1, frame)) end
一つ目のNSDefSplineで、フレーム番号から表示すべきx座標を計算する関数ができる。
同様に、二つ目のNSDefSplineで、フレーム番号から表示すべきy座標を計算する関数ができる。
mov %10,-1 ; フレーム番号とする。 *main inc %10 ; フレーム番号を増やす spline %10,%11,%12 ; フレーム番号に対するx, y座標を取得 drawbg drawsp2 100,0,255,%11,%12,100,100,0 ; スプライトを画面に書きこむ。 draw ; 画面に反映 wait 40 ; 1秒間24フレームだとこれくらい待つ。 if %10 < 51 goto *main ; フレーム番号がいっぱいになるまで繰り返す。
フレーム番号をずらしてみる。
中間の通過点に達するまでのフレームを遅くすると、そこまでゆっくり移動し、その後は早くなる。「溜め」の演出に……使えるかな?
NSDefSpline(0, {0, 35, 50}, {80, 80, 560}) NSDefSpline(1, {0, 35, 50}, {440, 40, 440})
始点と終点を一致させる。
始点と終点を一致させ、通過点を複数指定すると、戻ってくるような軌道にできる。
NSDefSpline(0, {0, 25, 50, 75}, {40, 560, 560, 40}) NSDefSpline(1, {0, 25, 50, 75}, {240, 40, 440, 240})
注意点
応用例
- フレーム番号を与えて座標を計算するので、巻き戻しも自由自在w
- 始点・通過点・終点の最低3点が必要だが、通過点は複数あってもよい。通過点の配置によっては、うねうねと蛇のように敵を狙う動きなどができる。
- もし、敵を貫通するようなアニメーションがしたい場合は、敵の位置を通過点にして、加えて、その手前の点と敵の位置をつないだ直線上画面外に終点を設定する必要がある。