ひぐ中様謹製DLLの使い方

これは動きがすごい - 永字八法の続き。殴り書きなので自分で読み返す気分になれない。困った。

ステップ1:define節にて使用を宣言

*define
setlayer 10,60,"MSpDraw.dll"

第一引数の10はレイヤー番号。何故10かと言えば意味はない。
ただ、http://gimite.ddo.jp/~kimikage/などで配布している同種のレイヤー型DLL(活動写真 Ver0.0とか)と同時に使おうとした場合、レイヤー番号を変えることで複数のDLLを区別できる。
layermessage 命令の第一引数はこの数値になる。
第二引数はレイヤーの更新頻度(ミリ秒)。NScripterはこの頻度でレイヤーにアクセスし、最新の状態にする。あまり数字を小さくしすぎると、他の動作に影響が出るのでほどほどに。

ステップ2:レイヤーとスプライトを関連付ける。

*start
lsp 100,"*10"

この例では、スプライト番号100に対してレイヤーを関連付けている。レイヤーによって描かれた内容が、スプライト番号100の前後関係で描かれると言う意味になる。
ちなみに、一つのレイヤーは一つのスプライトにしか関連づけられない。一度、あるスプライトと関連付けてしまった後で、別にlsp命令を行ってもそれは無視される。関連付けを解除しようと思ったら、cspでスプライトを潰してしまわなければならない。
また、同様に以下のようにしても無効になる。

*define
setlayer 10,60,"MSpDraw.dll"
setlayer 20,60,"MSpDraw.dll"
game
*start
lsp 0,"*10"
lsp 1,"*20"

このようにしてもレイヤーは一つ、最初に宣言したものだけが有効になる。
スプライト番号1による操作も有効ではあるが、それは全て同じレイヤーに対する操作と解釈される。(何を言っているかわからない場合は、「同じDLLに対してsetlayerを二度以上実行してはならない」と覚えること。わけの分からない事態はバグの元)
ただし、変則としてこのようなことはできる。

*define
setlayer 10,60,"MSpDraw.dll"
setlayer 20,60,"MSpDraw2.dll" ; MSpDraw2.dllはMSpDraw.dllのコピー
game
*start
lsp 0,"*10"
lsp 1,":a;normal.bmp",320,240 ; 普通の立ち絵
lsp 2,"*20"

こうした場合、自由自在に動くレイヤーを二つ用意したことになる。

ステップ3:レイヤーを操作する

あるレイヤーにグラフィックファイルを読み込ませて表示するには、以下のような操作が必要。

layermessage 10,"draw/(レイヤー内スプライト番号),(表示ファイル名:タグ使用可),(スプライトの中心のx座標),(スプライトの中心のy座標),(スプライトの不透明度:0で透明、255で不透明),(回転:反時計周りで360度),(横方向拡大率:小数使用、1は1倍の意),(縦方向拡大率:小数使用、1は1倍の意),(水平軸回転度),(アニメーション回数:-1で無限回数),(アニメーション一回あたりのx座標増加分),(アニメーション一回あたりのy座標増加分),(アニメーション一回あたりの不透明度増加分),(アニメーション一回あたりの回転度数増加分),(アニメーション一回あたりの横方向拡大率増加分),(アニメーション一回あたりの縦方向拡大率増加分),(アニメーション一回あたりの水平軸回転度増加分),(実際の表示をアニメーション指定回数度後に)"

ちなみに、中心のx座標,y座標までが必須の要素であり、その後の部分は全て省略が可能になる。
省略した場合は、それぞれ以下のような(推測)既定値が使われる。

パラメータ 既定値 備考
スプライトの不透明度:0で透明、255で不透明 255
回転:反時計周りで360度 0
横方向拡大率:小数使用、1は1倍の意 1
縦方向拡大率:小数使用、1は1倍の意 1
水平軸回転度 0
アニメーション回数:-1で無限回数 0 推測。アニメーションの指定がない場合、-1と0では区別がつかない。
アニメーション一回あたりのx座標増加分 0
アニメーション一回あたりのy座標増加分 0
アニメーション一回あたりの不透明度増加分 0
アニメーション一回あたりの回転度数増加分 0
アニメーション一回あたりの横方向拡大率増加分 0
アニメーション一回あたりの縦方向拡大率増加分 0
アニメーション一回あたりの水平軸回転度増加分 0
実際の表示をアニメーション指定回数度後に 0

ここで注意したいのはレイヤー内スプライト番号である。
NScripterにとってレイヤーはスプライトの一つでしかないが、レイヤーは内部にさらにスプライトレイヤーを複数持っている。このレイヤー内スプライトは、付属のMSpDraw.txtには「移動スプライト番号」として説明されている。なお、このスプライト番号は「0〜40」と記述されているが、実際にやってみると「0〜19」のようだ。20以上の数値を指定すると、警告メッセージが出てそのlayermessage命令は無視される。
また、このレイヤー内スプライトは番号が若いほど画面奥に表示される。NScripterの通常のスプライトとは逆の番号体系を持っているので間違えないように。

検証1:アニメーションの注意点

アニメーションしているかどうか、あるいは、アニメーションが終わるまで処理を待つ処理は、以下のようなスクリプトになる。

; ここに、なんらかのアニメーションを含むlayermessage命令が入る。
~
wait 5 ; 処理落ちを防ぐ意味で若干のwaitを入れる。
layermessage 10,"getphase/0" ; レイヤー内スプライトに問い合わせをする。
getret %100 ; 問い合わせの結果を取得して%100に代入する。
notif %100=2 jumpb ; 停止中でなければ上のニョロまで戻る。

このルーチンを使う場合は、必ず回数が限定されたアニメーションを使うこと。
もしアニメーション回数に-1を指定している場合、無限アニメーションしてしまうのでレイヤー内スプライトの状態が停止中になることは決してなく、上記ルーチンは無限ループになってしまう。これは不透明度などがアニメーションしていたとしても同じことなので、注意が必要だ。
逆に、一度停止状態になったレイヤー内スプライトは、アニメーションの指定をしてもそのまま動き出すことはなく、layermessage 10,"move/0"などの命令でもう一度動かさなければならない。一定の幅の内部で立ち絵を左右に動かすなどの処理をした場合、このmoveを忘れると決して意図した通りの動きにならないだろう。

検証2:nsaファイルとの関連

検証してみたが、nsa命令、addnsadir命令双方が有効に作用した。

俺様感想

ツールキットの主力にしようそうしよう。

追伸

と、こんな理解でいいですか?>ひぐ中様