NSCOMのチュートリアルやってみる
luasubと言うdefine節専用の命令が増えた。
これはdefsubのLua版であり、その命令の実体をsysytem.lua(もしくはその中からdofileで呼ばれるファイル)内に記述する。
たとえば、00.txtのdefine節に
luasub sample_function
と記述した場合、system.lua内では、最低でも、
function NSCOM_sample_function() end
と記述しなければならない。
そして意味のある命令を作ろうと思えば、引数の受け渡しなどをLuaで記述しなければならない。
実際に作ってみる
実は引数が一つの命令を作るのはそれほど難しくはないのだが、引数が複数になると途端にトラップが発動してしまうので、注意が必要だ。これで私も30分は悩んだ。
サンプルとして、max命令を作ってみる。
- 書式
- max 数値変数,数値,数値
- 説明
- 第二引数から第三引数までの数値変数の中で、最大の数値を持つ数値変数の番号を返す。
- 補足
- もし、最大の数値が複数あった場合は、その中で最初のものが選ばれる。
mov %100,0 mov %101,-3 mov %102,6 max %0,100,102 %0 ; 102と表示される
こんな感じ。
00.txt
*define luasub max game *start ; 状況を定義 for %0=100 to 109 rnd2 %%0,-10,10 %%0 / next ; 実行 max %0,100,109 最大値は変数番号%0の、%%0です。 click end
system.lua
function NSCOM_max() -- 関数宣言の後には必ず()をつけよう。 local res = NSPopIntRef() -- 第一引数の数値変数の番号を取得する。 NSPopComma() -- これがポイント。これがないと、第一引数にずっととどまり続ける。 local sn = NSPopInt() -- 第二引数の数値を取得 NSPopComma() -- 同じく、これがないと第二引数にとどまり続ける。 local en = NSPopInt() -- 第三引数の数値を取得 if sn > en then -- 数値が逆転していた場合、スワップしないと。 sn, en = en, sn -- ワオ! Perlチックsyntax sugar! end -- 他の言語経験者がよく忘れるのが、ifに対するendだろう。 local max = sn local max_num = NSGetIntValue(sn) -- 最初の数値を取得する。 for num = sn+1, en do -- for文もちょっと独特なんだよなあ。 local temp = NSGetIntValue(num) if temp > max_num then max = num max_num = temp end end -- 手動でmax処理してるけど野暮ったいとか言わないで! NSSetIntValue(res, max) -- 第一引数の数値変数に戻す return true -- 念のため end
デバッグのポイント
system.lua内で、Lua的シンタックスエラーがあると、エラーメッセージが出る。
上記の例だと、
[string "function NSCOM_max() -- 関数宣言の後には必ず()をつけよう。…"]:(エラー行): エラー内容
こんな風になる。エラーを起こした行数に注目してきっちりバグをとろう。ifの後のendを忘れてないか? たとえば、上記の例最初のifのendをコメントアウトすると、こんなエラーが出る。
[string "function NSCOM_max() -- 関数宣言の後には必ず()をつけよう。…"]:25: 'end' excepted (to close 'function' at line 1) near '<eof>'
この場合は、エラー行が信用ならないので、全てのfunction, if, for ,repeat, while……などを調べてendの有無を一つずつ確認していくべし。
作った後で
例が悪かったような気がする。これ別に普通にNScripterのネイティブで組んでいいレベルの内容。