カテゴリ:NSLua( 27 )
続・numalias話に便乗してみる
 実際のスクリプトはこんな感じ。

varindex = 100
varlist = {}
for line in io.lines("varalias.txt") do
line = line:gsub(";.*$","")
local var = line:match("[_a-zA-Z][_%w]*")
if var then
NSExec('numalias '..var..','..varindex)
varlist[var] = varindex
varindex = varindex + 1
end
end


 で、varalias.txtには
index
;以下、スプライト用
spx ;X座標
spy ;Y座標

 なんて書き方ができるわけです。
 ただ、このままだとアーカイブ化した時にvaralias.txtが読めなくなるので、一工夫必要です。
[PR]
by lyricist_m | 2010-04-15 13:07 | NSLua
numalias話に便乗してみる
 時間が無いので取り急ぎ。
 いっそのことnumaliasだけ別ファイル化しちゃうのはどうかなぁと。
 例えばnumalias.txtってのを用意して、中には
x,0
y,1
 って書く。それをNSLuaからforで回して取得、numaliasする。
 変数番号定義に特化するのであれば、varalias.txtの中に変数名だけ書いて、変数番号の設定はNSLua側でやる。
 ;(セミコロン)でコメントを書けるようにしてやれば、NScripterオンリーで分業してる人でも書けるし読めるのでは。アーカイブ中のテキストファイルでもNSGetFileInfo使えば読めますし。
[PR]
by lyricist_m | 2010-04-13 18:23 | NSLua
アンダーラインを引く
 本文にアンダーライン(正しくはアンダースコアというらしいですが)を引く方法です。
 NScripterだけでも再現できなくは無いんですが、改行無視のスラッシュへの対応が面倒になるので、NSLuaでやってます。
 以下、スクリプト。

function NSCOM_line()
local text = NSPopStr()
local len = #string.match(text, "^(.-)/?$") / 2
NSExec("getcursorpos %0,%1")
local x = NSGetIntValue(0)
local y = NSGetIntValue(1)
NSSpLoad(0, ":s#FFFFFFあ")
local width,height = NSSpGetInfo(0)
NSExec(string.format('puttext "%s"', text))
NSSpLoad(0, string.format(":s/%d,%d,0;#FFFFFF_", width * len, height))
NSSpMove(0, x, y, 255)
NSUpdate()
end


「line "あいうえお"」という風に使います。テキストの途中でアンダーラインを引きたい場合は
あい/
line "うえ/"

 こんな感じで。使いたい用途によっては、line命令中でスラッシュ付加してもいいかもしれませんね。
 このスクリプトではスプライトやNScripter側の変数を使ってるので、バッティングする場合は適宜変更で。
 問題点としては
・テキストウィンドウ非表示時にスプライトも一緒に非表示にしないといけない
・バックログでは表示されない
 ってところでしょうか。どちらもシステムカスタマイズすれば解消可能ではありますが、上はともかく下はちょっと面倒かも。
[PR]
by lyricist_m | 2010-03-15 18:34 | NSLua
NSLua周りの覚え書き
・string.subの引数は(対象文字列、切り取り開始位置、切り取り終了位置)。最初の文字は0番目ではなく1番目なので注意
・ダブルクォーテーションとシングルクォーテーションは適宜使い分けよう(例:NSExec('csvopen "test.txt","w"'))
・NScripterのメニューバーが操作されたら、対応するLuaの命令が呼ばれるようにする、ってできるようになると嬉しいかも。要望出してみようかな
・NSDoEventsのイディオム
if NSDoEvents() then return end
・NSGetMouse()は画面外だと-1が返ってくる
[PR]
by lyricist_m | 2010-01-25 16:57 | NSLua
保存と復帰
 自分で作ったテーブル周りのサンプルを使ってて、バグに気がつきました。テーブルにboolean型の値が格納されている場合にエラーが出ることと、格納されてる値の型情報が失われていることです。前者はすぐに対応できるんですよ。テーブルを文字列化する際にちゃんとtostring()してやればいいだけなので。問題は後者です。たとえばboolean型が複数個格納されているテーブルをCSVで保存し、復帰させたあと、復帰前のテーブルと復帰後のテーブルで値を逐一比較した場合、全部不一致になってしまうわけです。true == "true"はtrueになりませんからね。なので、何とかして型情報を正しく保存する必要があります。
 ひとつ思いついたのは、保存する時に格納する値の前にカッコで型情報を記述し、復帰させる時にstring.gmatch()で型情報を取り出す方法。たとえば{1,"2",true}というテーブルがあれば、それぞれを"(number)1","(string)2","(boolean)true"と変換するのです。これならいけそうですね。

 あと、自作サンプルではテーブル内にテーブルが含まれている場合もエラーが出ます。これも何とかしたいですね。
[PR]
by lyricist_m | 2009-07-23 18:39 | NSLua
アニメーション応用
 アニメーションコールバック(NSCALL_animation)を使用したサンプル(アニメーション応用)をDelusionist's Utopiaにアップしました。

 このスクリプトの特徴は、テーブルを使用することによって、一度の割り込みで複数の処理ができる点です。だいたいの流れは、まずテーブルに関数を登録し、割り込み時にテーブルを巡回して関数を呼び出し、処理を止める場合はテーブルから関数を削除する、という形になります。関数は呼び出される際にNSTiimerで取得した現在時間を渡されるので、それに応じた処理を行なうことにより、コールバックのインターバルに左右されない処理が可能です。逆に言えば、関数を記述する際はインターバルに左右されないように気をつける必要があります。できればインターバルを自動で調整(処理に時間がかかる場合は長めに、早く終わる場合は短めに)してくれるようにしたかったのですが、ちょっと微妙だったので今回は省きました。いい具合にスクリプトを組めたら更新しようと思います。
 で、コールバックで呼び出す関数のサンプルを3つ用意しました。時計を表示するclock命令と00からカウントアップしていくタイマーを表示するtimer命令、そしてマウスカーソルを徐々に移動させるmovemousecursor2命令の3つです。もっと数を増やしたかったのですが、時間に関する処理で思いついたのがこれくらいだったので……。まあ、複雑なことはしていないし、自分にしてはコメントをつけた方なので、そこそこ解りやすいかと思います。



 今回のスクリプトを組んでいて「複数のスプライトの移動を管理できる機構が欲しいなぁ」と思いました。吉里吉里のDefaultMover.tjsあたりを参考にして、書いてみようと思います。目標としては、あらかじめ読み込んでおいたスプライトの番号と移動方法、処理にかける時間なんかをLuaに渡すことで動かしてくれるような感じにしようかと。移動方法はせっかくスプライン補間があるから、それも使ってみたいですね。
[PR]
by lyricist_m | 2009-07-22 21:57 | NSLua
ローカル宣言を行なう場所に対しての注意
local a = "test"

luasub("test")
function NSCOM_test ()
NSExec('caption "'..a..'"')
end

--local a = "test"


 上記Luaスクリプトにおいて、上のlocal aをコメントアウトして、反対に下にあるlocal aのコメントアウトを外すと、エラーになります。どうやら、関数宣言より下にあるローカル宣言は、関数内からは見えないようで。test命令が呼び出されるのはNScripter側、つまりLuaスクリプトを全て読み込んだ後なので、ちゃんと変数aに値がセットされるものだと思ったのですが。ちなみに上記Luaスクリプトからlocalを外して通常の代入文にした場合は、上でも下でも普通に動きます。うーん、これってLuaリファレンス読めば書いてあるんだろうか。
 スクリプト中でローカル宣言をベタ書きする(関数外に書く)場合は、順番に注意が必要ですね。とりあえず、ローカル宣言はファイルの先頭にまとめて書いてしまった方がいいと思います。
[PR]
by lyricist_m | 2009-07-15 23:50 | NSLua
ゲームサンプル(ドッジ)をバージョンアップ
 幻惑郷 : ゲームサンプル(ドッジ)で上げたものをバージョンアップしました。

 LuaでOOP
 上記サイトさんを参考に、クラス周りを修正しました。前回とは「親クラスのメソッドが使える」点が大きく違いますね。実は当初こちらで製作していたのですが、どうもおかしなエラーが頻発するので泣く泣く簡単な実装で我慢することになったのでした。そして昨日、改めてほぼ同じスクリプトを書いてみたところ、なぜかエラーは出ず。未だに原因は解っていません。なんだったんだろうなぁ、一体……。
 それはともかくとして。やはりクラスが使えるとやりやすいですねぇ。ノベルゲームだと必要なさそうですが、こういうゲームゲームしたものだと便利です。クラス以外でも、メタテーブルを色々弄ればもっと便利になりそうですが、あまりやりすぎると可読性が落ちそうですね。作ってる当時はいいけどある程度時間を置いてから見直すと「これ、何やってるんだっけ?」ってなりそう。
 他の修正点としては、スペースキーでのポーズやエスケープキーでのゲーム終了などのキー入力周りですね。NSGetKey(checkkeyやbexecもそうですが)は基本的に、キーが押されるとすぐ処理が返ってきてしまうので、今までのボタン処理に慣れてると少し苦労します。キーダウンじゃなくてキープレスを取得する関数でも作るべきかなぁ。
[PR]
by lyricist_m | 2009-05-09 16:49 | NSLua
returnとbreakについて
 Luaのリファレンスマニュアルに「return 文と break 文はブロックの 最後 の文としてのみ書くことが許される」と記述されていますが、基本的に気にしないでいいです。
 一般的にreturnとbreakを書くタイミングって、ブロックの最後以外に来ることがまず無いんですよね。
 たとえばbreakの場合、
while true do
if NSGetKey("RETURN") then break end
NSSleep(1)
end

 といった使い方をするわけですが。
「最後の文」と書かれているのでなんとなく「whileの最後に来てないし、こういう書き方だめなのかなぁ」という気になりますが、if文のブロック内の最後の文になっているので、これは正しい使い方になります。
 もしわざと不正な使い方をするのであれば
while true do
if NSGetKey("RETURN") then
break
NSExec('caption "RETURN key is pressed"')
end
NSSleep(1)
end

 という感じですね。もしこういう書き方をするとしたら、デバッグしたい時なんかでしょうか。ループや関数を途中まで進めて様子を見たい、とか。そういう時は単にbreakと書くのではなくdo break endとしましょう。

 ちなみに、returnとbreakで不正な使い方をした場合、「'end' expected...」というエラーメッセージが出ます。
[PR]
by lyricist_m | 2009-05-09 15:57 | NSLua
ゲームサンプル(ドッジ)
 NSLuaで作成した簡単なゲームのサンプルをアップしました。Delusionist's Utopia -NScripter-からDLできます。

 ゲーム内容は「出現する敵をただひたすら避け続ける」というシンプルなもの。カーソルで自機を操作でき、一定時間を経過すると勝利、敵に当たると敗北です。
 特徴は
・ほぼNSLuaのみで作成されている
・アニメーションを使用していない(延々ループを回している)
・簡易クラスを用いている
・簡単なFPS調整を行なっている
・スペースキーによるポーズに対応している
 といったところでしょうか。
 個人的にはクラスの機構をもうちょい弄りたかったなぁ。実は別の方法でクラスを実装していたんですが、どうも親クラスの参照がおかしいらしく、親クラスから継承したインスタンス変数がインスタンス間で共有されちゃってたんですよね。色々頑張ってみたものの問題を解決できなかったので、簡単な方に移行しました。これだと子クラスで親クラスの関数を呼んだりできないので、次はそこらへんを改善したいですね。



 あと、同じくNSLuaサンプルである「テーブル周り」のリンクがおかしかったのをついでに修正しました。
 おかしいなぁ、確認したと思ったんだけど。
[PR]
by lyricist_m | 2009-05-07 20:43 | NSLua