<   2007年 05月 ( 9 )   > この月の画像一覧
システム層とゲーム層の分離
 何個かゲームを作ってきたのですが、今まで大体の基幹部分を1から作り直してたんですよね。作ろうとするたびにスクリプトの書き方が違っていたり、ファイル・フォルダの構成を変えたりしてましたから。
 でも、これじゃあいかん、効率が悪すぎるなとようやく気付きました。
 どんなジャンルのゲームにも使える一般的な「システム層」と、個々のゲームに特化した「ゲーム層」に分離し、システム層はどんどん使いまわしていくと効率がいいんじゃないかな、と思ってます。
 システム層にはまず一番上位にシステムがあって、その下位にテキスト、イメージ、サウンドが並んでる感じ。これらはライブラリみたいなもんで、、あくまで呼び出されるだけです。内部でなんらかの処理をすることはあっても、gotoでゲーム層からシステム層に飛んだりはしません。
 ゲーム層でカスタムウェイトやカスタムセレクト、エフェクト、右クリックメニュー、ログなどの実装。

 問題は、システム層とゲーム層の切り分け。セーブ・ロードの画面自体はゲーム層だろうけど、内部的な処理は一部システム層に預けちゃってもいいんじゃないかって気がするんですよね。*define_saveと*define_gamesaveとかで分けようかなぁ。
[PR]
by lyricist_m | 2007-05-31 21:49 | NScripter
btndownとisdown
 btndown命令とisdown命令、今まであまり使ったことがなかったんですが(未完成のマウスジェスチャースクリプトでちょこっと使ったくらい)、次に作りたい作品に必要そうだったんで、使い方とかちょっと調べてみました。

 まずNScripter本体付属のマニュアルを新・旧ともに見てみたのですが、両命令とも発見できず。
 こういうときはsenzogawaさんのNScripter API Reference (Unofficially)だ!
 ということで以下に両命令の説明を抜粋。

btndown
「btndefとbtnwait系命令の間に挟んでください。
そのボタン命令において、ボタンの押しっぱなしを取得できるようにします。」
isdown
「ボタン押下中かどうかを判定して結果を変数に格納する。
離していれば0、押していれば1が返る。」 

 つまり、isdown命令で結果を取得したい場合はbtndown命令を忘れるな、と。ここらへんgettab命令などのキー拡張命令と似てますな。

 ちょっと長くなるので続きは下のリンクをクリックしてください。
 

More
[PR]
by lyricist_m | 2007-05-29 23:23 | NScripter
textgosubで指定したラベルに飛ぶタイミング
 ふと気になったので、ちょっと調べてみた。以下が検証用スクリプト。textgosubでラベルに*textlbを指定している。*textlb直下にclick命令を使っているので、*textlbに飛んだ直後にクリック待ちが入るため、どのタイミングでラベルに飛んだかがわかる。

*define
textgosub *textlb
game

*textlb
click
btndef clear
*textlb_btnwait
textbtnwait %0

if %0 == 0 goto *textlb_end
goto *textlb_btnwait
*textlb_end
texec
saveon
return

*start
あいうえお@
end

 検証の結果、どうやら@や¥がきたらラベルに飛ぶようだ。言い換えるなら、@や¥がくるまで文章を表示し続ける、と。



 余談だが、なぜこれを調べたかというと、「textgosubで飛んだ直後に命令はさんで、文章を表示させる前にしたい処理をやれたりしないのかな」なんて思ったから。
[PR]
by lyricist_m | 2007-05-28 13:53 | NScripter
intlimitとfor
 現在製作中のゲーム、迷宮(仮)の背景表示スクリプト作成用スクリプト(ややこしいな)を作っていたところ、for文でループしてしまい脱出できないという現象が発生した。調べてみたところ、どうやらintlimitが原因のようだ。
 以下がその現象の起きる最小のスクリプトである。無限ループにするとNScripterが固まるため、waitを挟んでいる。
*define
intlimit 0,0,1
game

*start
for %0 = 0 to 1
wait 5
next
end

 %0が1より大きくなったらfor文のループから出るのに、intlimitで最大値が1に指定されてしまっているために延々とループしてしまったようだ。
 普段あまりintlimitを使うことが無かったから気付かなかった。もしintlimitを使うことがあったらfor文には気をつけよう。
[PR]
by lyricist_m | 2007-05-25 16:54 | NScripter
デフォルト機能をそっくりそのまま再現
 これまたふと思いついたこと。
 NScripterがデフォルトでやってくれている機能、例えばページ送りとか右クリックとか回想とかセーブロードとか、そういうのを自分でそっくりそのまま再現してみようかと思います。
 一度作ってしまえばあとはそれに手を入れていくことで自分好みの形に持っていけるでしょうし、そのスクリプトを公開したらこれからNScripterを始める人の役に立つんじゃないかと思ったんで。やるからには命令もサポートしたいところですね。例えばmenuselectcolor命令を使ったらちゃんと右クリックメニューのテキスト色が変わるとか。
 現在、回想から取り掛かってます。命令まで作りこむのは時間が掛かりそうなので、とりあえず形になったら公開します。
[PR]
by lyricist_m | 2007-05-18 23:14 | NScripter
maxkaisoupage命令の挙動
 ふと気になったので試してみた。

 maxkaisoupage命令は「回想モードの最大ページ数を設定する命令」だが、実際のところどんなことをしているのだろうか。
 単にデフォルトの回想に関する設定ならば、回想モードを自作した場合は必要のない命令なのだろうか。
 ということで、簡単な検証スクリプトを書いてみた。

*define
maxkaisoupage 1
game

*start
あ\
い\
checkpage %0,2
if %0 == 1 puttext "成功\"
if %0 == 0 puttext "失敗\"
getlog $0,2
$0\
end

 \は半角円マークだと思って欲しい。
 これは、maxkaisoupage命令で回想モードのページ数を1ページに設定し、checkpage命令で2ページ前のログが取得可能か試すスクリプトだ。動かしてみたところ、「失敗」と表示された。また、getlogで2ページ前のログを取得できないかと思ったが、実際取得されたのは1ページ前のものだった。
 maxkaisoupage命令に2を設定すると成功し、ログも取得できた。

 以上の動作から、maxkaisoupage命令は厳密には「回想モードのバッファサイズを指定する命令」と言うべきのようだ。なので、自分で回想モードを作る時には忘れず使うべきだと思う。じゃないと、折角スクリプトでは何十ページと表示できるようにしていても実は5ページしか表示されません、となってしまって実に勿体無い。

 あとこのスクリプトで気がついたのだが、getlogはログが取得できない場合、回想バッファに格納されている一番古いログを返すようだ。
 例えばこのスクリプトの場合、2ページ前のログは取得できないため、回想バッファに格納されている一番古いログ、つまり1ページ前のログが返ってくる。また、このスクリプトのmaxkaisoupage命令に十分大きな値をセットし、getlogで「あ」より前のページのログを取得しようとすると、返ってくるのは「あ」である。
[PR]
by lyricist_m | 2007-05-17 21:44 | NScripter
可変個の引数をとれなくてもいいじゃない
 別に引数の数を可変にしなくても、mov3~mov10命令みたいにすりゃいいんじゃね、と思った。省略したらデフォルトの値を使う、なんてやり方はできないけど。

 試しに、文字列用のmov3~mov10を作ることを考えてみる。たしか文字列でこれらの命令は使えなかったと思うので。考えるだけなので、実装してみたら問題が出るかもしれない。
 まず、増減する引数の、最大の個数を決定。とりあえずここでは10個。そしてその個数分の変数を命令用に確保する。10個なので、$0~$9まででいいだろう。
 そしてgetparamで値を受け取る。mov3ならgetparam s%0,$0,$1,$2、mov10ならgetparam s%0,$0,$1,...,$9ってところか。で、%1に引数の個数を代入するか、使わない変数(mov3なら$3~$9)をクリアするか、どちらかをしておく。
 そのあとメイン処理部分に飛ばす。ここはmov3~mov10の全命令において共通。for文で%1の回数分ループを回すか、ラベルとgotoでループをつくり、空文字("")だったらリターンするようにする。後者の場合、文字変数のクリアをリターン前にしてもいいかもしれない。

 こんな感じで、単に処理対象が増えるだけの命令ならメインの処理部分を使いまわしできそう。ラベルとgetparamの部分はNScripterを利用して作成できると思う。
[PR]
by lyricist_m | 2007-05-15 22:48 | NScripter
seteffectspeed命令(2)
 前回の続き。
 スクリプトは完成したのですが、公開できるような書き方をしてないので、後日書き直したものを追加します。

 それでは、まずseteffectspeed命令が適用される命令について。テストした命令を「適用された命令」と「適用されなかった命令」の二つに分けて箇条書きします。

 適用された命令
・bg
・ld
・print
・lsp & print
・csp & print

 適用されなかった命令
・wait
・delay
・waittimer
・quake
・flushout

 この二つの命令群は「エフェクト番号を指定できるか否か」という点に違いがあります。適用された命令ではエフェクト番号で指定、或いは効果番号+時間で指定でき、適用されなかった命令は概ね時間のみです。
 つまり、seteffectspeed命令は「エフェクト番号=(効果番号+時間)の時間を変化させる命令」と言えるようです。
 なので例えば、もしオプションでエフェクト速度を変更できるようにして、その実装にseteffectspeed命令を使用し、なおかつquakeやflushout、演出用waitの速度も変更したいような場合は、自分で色々工夫してやらなければいけません。
[PR]
by lyricist_m | 2007-05-14 22:41 | NScripter
CSV、行の終端
 csvread命令を上書きできたら、CSVファイルの行の終端に特殊文字(或いは数字)を仕込むことでcsveol(csv end of line)命令を自作できそうなんですが、問題はcsvread命令の引数が不定であること。スクリプト側で可変引数の命令は自作できませんからね。たぶん。

 引数の個数を固定にしてcsvread2_num,csvread2_strとか作っちゃえばいいですかね。
 そしたら、上記の命令の中で行の終端に達したかどうかを判断し、フラグを立てる部分を追加すればいいだけです。
 で、csveol命令でフラグを返せば行の終端に達したかどうか解る、と。考えてみたら簡単でしたな。



 現在製作中の迷宮探索ADV、マップの仕様がまだ決まっていないので(横縦の要素数とか)、とりあえずこの命令で作ってみようかな。
[PR]
by lyricist_m | 2007-05-07 21:45 | NScripter