<   2009年 04月 ( 18 )   > この月の画像一覧
Luaスクリプトを新規作成するバッチファイル
@echo off
rem Luaスクリプトを新規作成します
set /p FILENAME="ファイル名を入力してください>"
echo --%FILENAME%.lua> %FILENAME%.lua


 上のように書いたバッチファイルを作ると、ファイル名を入力するだけで「ファイル名.lua」というファイルを作成してくれます。
 ちなみに、Luaスクリプトのファイルの一行目に書いた内容がエラーメッセージに出力されるそうです。なのでこのバッチファイルではファイルの一行目にファイル名を書いています。



 バッチファイルは便利ですねぇ。
 複数行に渡ってテキストを書けたら、*defineとgameと*startだけを書いた00.txtを作るバッチファイルでも作るところなんですが、そっちはむしろエクスプローラの新規作成を弄った方がいいかな。
[PR]
by lyricist_m | 2009-04-30 16:33 | NSLua
引数の個数チェック
 luasub用の関数の最後で
if NSCheckComma() then
NSOkBox("引数が多すぎます","関数名")
end

 って書けば、引数の個数チェックが出来ます。

 今までは、引数が少ない場合ならエラーが出ていましたが、引数が多い場合は余計な引数を表示文として解釈していました。
 そのため、前者よりもバグの検出がしづらかったのですが、Luaのお陰で検出が可能になりましたね。いいことです。
[PR]
by lyricist_m | 2009-04-29 20:28 | NSLua
変数の衝突を回避する
・ファイルを越えて変数を利用する場合
 localをつけずに使用する。関数の内外を問わない。

・ファイル内だけで利用したい場合
 localをつけ、関数外で宣言する。

・関数内だけで利用したい場合
 localをつけ、関数内で宣言する。



 こんな感じでしょうか。
[PR]
by lyricist_m | 2009-04-28 14:44 | NSLua
NSExec()の重複
 NSExec()でluasubの命令を呼び出し、その中でまたNSExec()を使用すると、NScripter側のスクリプトの現在位置がリセットされ、00.txtの冒頭から読み直すみたいです。
 呼び出された命令中でNSGoto()をすることで読み直し始める箇所を指定することはできますが、そもそも「NSExec()の重複」は禁止されている使い方なので、やめたほうがいいでしょう。
「何でか解らないけど00.txtに飛ばされるなー」という場合は、どこかでNSExec()が重複していないか、一度チェックしてみることをおすすめします。
[PR]
by lyricist_m | 2009-04-27 22:53 | NSLua
luasubをLua側から呼び出す
 Luaのスクリプト中に
NSExec("luasub test")
 のように記述すれば、NScripter側でluasubを記述しなくても済む。
 つまり、luasubを含むライブラリを作成しておき、system.luaからライブラリをNL_dofileで読み込めば、自動で命令が追加されるわけですね。わー便利。

 余談ですが。
 luasubした命令は、定義節中では呼び出せません。
 Luaスクリプトが読み込まれていないため、「そんな命令は存在しない」とエラーが出てしまいます。
「IDが取得できるなら、numaliasをカスタマイズできるんじゃね?」と思ったのですが、上記の理由で無理でした。残念。



[追記]
 luasubした命令は、定義節中では呼び出せません。
 が、system.luaで何もないところに
NSExec("luasub test")
NSExec("test")

 と書くと、luasubした命令を呼び出せます。あまり意味はありませんが。
 また、luasubと同様にnumalias・straliasも使えます。
[PR]
by lyricist_m | 2009-04-27 12:09 | NSLua
Luaのテーブル周りメモ
・関数の戻り値でテーブルを初期化する場合
function f ()
return "x","y","z"
end
 という関数fがあるとする。
t = {f()} は t = {"x","y","z"} と同じ
t = {"a","b",f()} は t = {"a","b","x","y","z"} と同じ
t = {"a","b",f(),"c"} は t = {"a","b","x","c"} と同じ
 {}の最後に関数のときだけ、戻り値が全部格納されるらしい。
 また、戻り値の展開を回避したい時はt = {(f())}と、関数をカッコでくくるといい。

・テーブルの各要素を巡回
 これにはいくつか方法がある。
1.for&pairs()
●書き方
for k,v in pairs(t) do
end
●概要
 一般的な書き方。巡回する順番は不定である。

2.for&ipairs()
●書き方
for i,v in ipairs(t) do
end
●概要
 t[1]から、最初にnilが返ってくるまでの間、ループを繰り返す。
 テーブルを配列のように扱っている時はこの方法を使う。

3.while&next()
●書き方
k,v = next(t)
while(k)
--処理
k,v = next(t,k)
end
●概要
 たぶん1.と変わらない。

4.for&#
●書き方
for i = 1,#t do
end
●概要
 ipairs()を使用した場合、途中の要素がnilだと(例:t = {1, nil, 3})、テーブルの終端に到達する前に処理が終了してしまう。要素にnilが含まれている場合でも終端まで処理したい場合はipairs()ではなくこちらの方法を使う。

・table.concat()
t = {"1","2","3"}
 というテーブルを、
1,2,3
 といったcsvみたいな文字列にしたい場合は、table.concat(t, ",")で事足りる。
(注意事項)
 連結されるのはキーが数値の要素だけで、キーが文字列の要素は含まれない(例:t["x"]など)。
 また、キーが数値の場合でも、キーの間が飛んでいる場合は、連続している部分のみ連結する。(例:t[2]の次がt[4]である場合、t[1]とt[2]の要素だけを連結する)
[PR]
by lyricist_m | 2009-04-27 08:21 | NSLua
ボタン拡張
 NScripter&Luaのサンプル、ボタン拡張スクリプトをアップしました。Delusionist's Utopia -NScripter-からDLできます。

 bexecなどの新ボタン系命令では、スプライトボタンをカーソルで選択して決定する、ということができません。bexecがカーソルの入力も捉えてしまうからです。これはちと不便だなと思ったので、カーソルで選択できるようにしてみました。
 まずはbspとbclearを上書き。bspでスプライト番号をLuaでテーブルに保存、bclearでテーブルを初期化します。次にspfocusnext、spfocusprev、spexecの3命令を追加。spfocusnextで次の、spfocusprevで前のスプライトにフォーカスを移すことができます。スプライトにフォーカスを移した状態でspexec命令が実行されると、選択されたスプライトの番号を得ることができます。使い方としては下のような感じ。
*loop
bexec $0,%0
if $0 == "UP" spfocusprev:goto *loop
if $0 == "DOWN" spfocusnext:goto *loop
if $0 == "RETURN" spexec %0
if %0 != -1 ;ここにスプライトが押された場合の処理を書く
goto *loop


 そこそこ使い勝手はいいと思うのですが、このスクリプトはまだ問題を残しています。
 たとえば「スプライトにフォーカスを移した状態でspexec命令が実行されると」と書きましたが、単にスプライトにマウスカーソルが重なっている状態でspexec命令が実行されてもスプライトの値は返ってきません。これはspexec命令が値を返す条件が「命令が実行された際にスプライトの左上座標とマウスの現在位置が重なっているか」というものだからです。
 スプライトの幅・高さからマウスカーソルがスプライト上に存在するかを判断してもいいのですが、もし新ボタン命令が透過ボタンに対応したらbexecとspexecで動作が食い違う可能性が出てきますし、そもそもマウスを動かせるのにクリックじゃなくてキーボードでボタンを選択するのも変な話です(ノートPCならありうるのかもしれませんが。タッチパッドの左ボタンよりキーボードの方が押しやすいとか)。
 なのでとりあえずは現状維持で行こうかなと。

 他にボタン命令を使いやすくできるアイデアが思いついたら、このボタン拡張スクリプトに盛り込むことにします。
 さて、次はテーブル周りとファイルの入出力でもやろうかな。



[追記]
 よく考えたら、透過ボタンの場合はスプライトの左上座標にカーソルを持っていってもボタンに重なるとは限らないんですよね。それなのにspexecで値が返ってきて押下処理されちゃうと、「カーソルが重なった状態」を飛び越して一気に「ボタンが押された状態」に行ってしまうことに……。うん、困った。
 旧ボタン命令でtransbtnを使用した場合、カーソルでスプライトを選択すると「透過されていない一番左上の部分」にカーソルが移動するようです。これと同様の処理を新ボタン命令でやるには、スプライトから1ピクセル抜き出して色・透過情報を調べられる命令を作ってもらうか、スプライトに対する当たり判定命令を作ってもらうかしないと、透過ボタンに対応するのは難しそうです。

[2009年5月11日追記]
 最新版でbexec命令が更新され、カーソルキーでの選択がデフォルトで可能になりました。btrans命令が追加されて透過ボタンにも対応。また、フルカスタマイズ用にスプライト系の命令がいくつか追加されるとのことです。
 ということでカーソルキー関連は、今後はそちらで対応することにしましょう。
[PR]
by lyricist_m | 2009-04-26 18:12 | NSLua
新ボタン命令について
 2009年4月26日時点での話。

・bexecの引数の受け取り方は下の通り。
bexec $0
bexec %0
bexec $0,%0
bexec %0,$0
 ただし、bexec %0,$0の場合はどうも動作がおかしい(クリックしても反応しないことがある)ので、使わないほうがいい。更新.txtに書いてある通りbexec $0,%0を使うべき。
・transbtnは機能しない。つまり透過部分を無視したボタンは作成できない。
・isdownは使えない。checkkeyでもマウスの押しっぱなしは検知できない。
・マウスをNScripter上の何もないところからドラッグ開始→ボタンの上で離す→ボタンが押されたことになる
[PR]
by lyricist_m | 2009-04-26 17:19 | NSLua
セーブとキャプション
 ロードしてもcaptionは復元されません。
 例えば、
caption "test"
savegame 1
click
caption "test2"
loadgame 1

 なんてスクリプトを実行した場合、loadgameをしてもcaptionは"test2"のままです。
 なので、章ごとにcaptionを変えるようなゲームの場合は、セーブ時にcaptionを文字変数に格納、loadgosubで復元、という作業が必要になりそうです。
[PR]
by lyricist_m | 2009-04-26 15:37 | NScripter
Luaで剰余の結果を調べてみた
10 % 3 = 1
10 % -3 = -2
-10 % 3 = 2
-10 % -3 = -1

 剰余演算子の振る舞い - codemagicを見るに、PerlやPythonと同様のようで。
[PR]
by lyricist_m | 2009-04-25 19:29 | NSLua