![]() |
![]() |
この文章を書いた時点でのVRM4のバージョンは「4.0.0.4」です。これ以前のバージョンではうまく動作しません。また、今後のバージョンアップによって仕様が変更される可能性もあります。 |
では、いよいよスクリプトによる制御の第一弾として、ポイントの切り替えをやってみます。VRM3にあった機能「キーボードのキーを押すとポイントが切り替わる」というのをスクリプトで実現します。
実験用のレイアウトを用意しました。えれぇ細長いですが、この左右にも編成の長さに対して十分なレールがあります。
まず、やりたいことを整理します(仕様書を書く訳ですな)。「キーボードのキーを押す=原因」と「ポイントが切り替わる=結果」の2つに分けて考えます。「ポイントが切り替わる」というのは色々解釈できるので、具体的に定義しないといけません。後々のことを考えて、現在の状態に関らず、「ポイントがレイアウト図の上方向に切り替わる」および「下方向に切り替わる」の2つの機能を持たせることにします。そして、これに対する原因(操作)として、「"p"キーを押す」と「"q"キーを押す」の2つを用意します。つまり、、「"p"キーを押すとポイントが上方向に切り替わる」「"q"キーを押すとポイントが下方向に切り替わる」の2つの動作をプログラムします(注1)。
注1:VRM3では、1つのキーを押すごとにポイントが現状と反対方向に切り替わる、という相対的な動作でしたが、敢えて、上記のような動作にしました。その理由は応用編で説明します。
結果の方からプログラムしていきましょう。目的のポイントを右クリックしてメニューから「ポイント設定...」を選択すると、ポイント窓が開きますので、「スクリプトエディター」ボタンをクリックします。
まず最初に1つ重要な確認です。それはこのポイントを他と区別できるように名前を付けることです。デフォルトで「POINT8」なんて名称が付いていますが、「PNT01」という名前に書き換えてみます。この名前の設定はスクリプトを組む前に行ってください。名前を変更すると、それに関連する全てのスクリプトを手直ししないといけなくなり大変面倒ですので。名前が決まったら、以下を入力します。
//Point Side BeginFunc P_ue Var p GetPointBranch p ifzero p set p 1 SetPointBranch p endif EndFunc BeginFunc P_sita Var p GetPointBranch p if p set p 0 SetPointBranch p endif EndFunc |
BuginFunc〜EndFuncの間がメソッド(サブルーチン・手続き)です。2つの動作をさせますので、2つあります。これも名前を付けて他と区別する必要がありますので、それぞれ「P_ue」「P_sita」と名付けBuginFuncの隣に書いておきます。(命令語がpointとか英語なので自分で名付けたものには日本語名を付けて区別するのは私の癖です。この辺は皆さんの流儀でどうぞ。)「P_ue」について説明しますと、まず、GetPointBranchで現在のポイントの状態を取得します。pnt=0で直進側、pnt=1で分岐側です(例題のレイアウトでは上方向=分岐側)。もしpnt=0(直進側)だったら切替えないといけませんので、pnt=1としてSetPointBranch命令でポイントを操作します。pnt=1(分岐側)ならばすでに切り替わっていますので何もしません。これをプログラムで書いたのが上記のifzeroなんとかの部分です。「P_sita」は、これの逆の動作となります。
プログラムの中身はもっとスマートな書き方があるかも知れません。しかし、ここで1つ重要なのは、BuginFunc〜EndFuncの間は他のスクリプトからは見えませんし影響を受け/与えることもありません。つまり、ブラックボックスという訳です。内部で何をやっているのか知らんが、「PNT01」君の「P_ue」とやらを呼び出すとポイントが上方向に切り替わる、ということが実現されればよいのです。
「キーボードの"p"を押す」という行為は、SetEventKeyで設定します。メニューのスクリプト編集を開いて、以下を入力します(注2)。
注2:このスクリプトは上記のポイントスクリプトに書くこともできますし、その方が簡単ですが、原因と結果ははっきりと分けて処理すべきです。その利点は応用編で分かります。
//Main Var pID1 Var pID2 SetEventKey this M_ue pID1 p SetEventKey this M_sita pID2 q BeginFunc M_ue call "PNT01" P_ue EndFunc BeginFunc M_sita call "PNT01" P_sita EndFunc |
SetEventKeyの後ろにいっぱい並んでいますが、これは後ろから読んだ方が理解しやすいです。「p」は押されるキーそのものです。「pntID1」は、登録番号のようなもので、このイベントを他と区別するためのものです。このイベントが発生すると勝手に設定されますので気にすることはありませんが他と重ならない名前にします。「M_ue」はキーが押された時に実行すべきメソッドで、「this」はそのメソッドが「この」場所にあることを示しています。SetEventKeyは、キーが押された時に何をするかを宣言するだけです。「p」が押されたら「M_ue」を呼び出してちょ、という訳です。実際、何をやるかは「M_ue」メソッドに書きます。
続けて、「M_ue」メソッドと「M_sita」メソッドを書く訳ですが、これらの中身は、ポイントで設定したメソッドを呼び出すだけです。「M_ue」メソッドの場合は「P_ue」を呼び出せばいいのですが、「P_ue」がどこにあるのかも指定してあげないといけません。そこで、「PNT01」という名前(オブジェクト)を指定します。つまり、「p」を押すと「PNT01」の「P_ue」が呼び出されポイントが切り替わるということになります。「q」を押した場合も同様です。
さて、これで動く筈です。ビューアーを起動して、コンソールで確認しながら「p」「q」キーを押してみてください。ポイントの記号が「|」と「/」に切り替わりましたか?