BeInteractive!

昨日のエントリfladdict.netさんで紹介されて浮かれております。という訳で、続きです。

そもそも、どういう時にスクリプトエンジンが必要になるのか?という所ですが、元々このエンジンはゲームを製作しやすくしようプロジェクト(今勝手に命名)の一環として作ったもので、やはりゲーム系なんかで役に立ちそうです。

とりあえず、このスクリプトエンジンの特徴と仕様を書いてから、いくつか使用例を挙げてみるので、そこからスクリプトエンジンの使い道を探ってみてください(笑

ではまず、特徴&仕様。

バイトコードインタプリタ

このスクリプトエンジンでは、一旦スクリプトをバイトコード(的なもの)に変換してから独自のVirtualMachine上で実行するという、JavaとかFlashとかと同じ方式でスクリプトを実行してます。

それなりに速度には気を配っているので、そこまで激重では無いと思う・・・。

ECMA-262ほぼ準拠

文法はECMA-262 3rd Editionにほぼ準拠してます。ActionScript1的な感じで記述できます。ASの機能は大体使えると思います。

  • try-catch-finally
  • for-in構文
  • ビルトインクラスのnew

には対応できていません。ビルトインクラスのnewは何だかコンストラクタの呼び出しがうまくいかず・・・。ビルトインクラスを使いたい人は、ファクトリメソッドを作ってエクスポート(後述)して使ってください。

// BitmapDataクラスのファクトリメソッド
function createBitmapData (width:Number, height:Number, transparent:Boolean, color:Number) : BitmapData
{
    return new BitmapData(width, height, transparent, color);
}

ActionScriptとのシームレスな連携

スクリプトエンジンは独自のコンテキストで実行されますが、スクリプトからActionScript側で用意した関数を使ったり、逆にスクリプト内で定義した変数や関数にActionScript側からアクセスすることが出来ます。

ActionScript側は、VirtualMachine#getGlobalObjectメソッドで、スクリプトエンジンのGlobalオブジェクトにアクセスできます。

スクリプトが、

var a = 'hello';
function f (a, b)
{
    return a + b;
}

となっていて、これを1度実行した後であれば、ActionScript側からは

// vmはVirtualMachineのインスタンス
trace(vm.getGlobalObject().a); // 出力 : 1
trace(vm.getGlobalObject().f(1, 2); // 出力 : 3

というように、変数・関数にアクセスできます。

逆に、ActionScript側で

vm.getGlobalObject().v = 'world'; // 変数を作る
vm.getGlobalObject().trace = trace; // trace関数をエクスポート

とかやっておけば、スクリプトで

trace(v); // 出力 : v

といったように、そのまま使うことが出来ます。

コルーチン

これ(Wikipedia)です。中断と継続です。

スクリプトに

suspend;

又は

yield;

と書くことによって、処理を一旦中断することが出来ます。中断すると、VirtualMachine#executeメソッドが終了し、再びexecuteメソッドを呼び出したときに、前回の続きから再開することが出来ます。

trace(1);
suspend;
trace(2);

というスクリプトがあったとして、これをActionScriptで実行すると、

vm.execute(); // ここで1が出力される
// 出力された後、suspendがあるので一旦処理は中断される

// 再びexecuteを呼ぶと、続きから再開されるので、
vm.execute(); // ここで2が出力される

となります。

コルーチンを使うことによって、状態遷移を簡潔に書くことが出来るようになります(使用例をご覧あれ)。

ちなみに、function内ではsuspendは使えません。suspendする必要がある場合は、coroutineキーワードで関数を定義してください。

// これはダメ
function sleep (n)
{
    while (n--) {
        suspend;
    }
}

// これならOK
coroutine sleep (n)
{
    while (n--) {
       suspend;
    }
}

何でこんな風になっているかというと、functionは純粋な関数なわけで、ActionScriptからも呼び出せるのでsuspendされたら困るからです。coroutineは関数のように見えますが、実体は関数ではありません。

function f () {}
coroutine g () {}

trace(typeof f); // 出力 : function
trace(typeof g); // 出力 : object

なので、coroutineをActionScriptから呼び出すことは出来ません。また、function内からcoroutineを呼び出すと、coroutine中のsuspendは無視されます。

ちなみに、coroutineは内部的にはただのジャンプなので、functionより高速に動作します。

言語使用拡張し放題

勿論、スクリプトエンジンのコードを弄れないとダメなのですが、↑のコルーチンのように、気軽にその場にあったスクリプト仕様を作ることが出来ます。

このスクリプトエンジンでも、コルーチンの他に、loop構文という、無限ループ用の構文を追加しています。


では次に、いくつか使用例を挙げてみます。

データの切り離し - JSON的な使い方?

例えばタイピングの問題など、頻繁に変更がありそうなデータなんかを、外部ファイルにしておいて、swfの再パブリッシュ無しに変更できます。

var qlist = ["あいうえお","かきくけこ", ... , 'すくりぷと'];
var rlist = ['AIUEO', 'KAKIKUKEKO', ... , 'SUKURIPUTO'];

ActionScript側でこれを1度実行した後、

var qlist:Array = vm.getGlobalObject().qlist;
var rlist:Array = vm.getGlobalObject().rlist;

と、簡単にデータを読み込むことが出来ます。

状態遷移を簡潔に書く

例えば、シューティングのステージデータ(敵がどこで出てくるとか)なんかどうでしょう?

敵生成用の関数をエクスポートしておいて、現在何フレーム目かを現す変数currentFrameもエクスポートしておいて、

// 指定フレーム数だけ待つ関数
coroutine wait (n)
{
    while (n--) {
        suspend;
    }
}
// 指定フレームになるまで待つ関数
coroutine waitFor (n)
{
    while (currentFrame < n) {
       suspend;
    }
}

// ここから
createEnemyA(); // 敵Aを生成
wait(3); // 3フレーム待つ
createEnemyB(); // 敵Bを生成
wait(2); // 2フレーム待つ
createEnemyA();
createEnemyC(); // 敵AとCを生成
waitFor(20); // 20フレームになるまで待つ
createEnemyB(); // 敵Bを生成
...

と、スクリプトを直感的に書くことが出来ます。

evalの代替手段

Flashにはマトモなevalが無いので、その代わりとして使えるのではないでしょうか。少し弄れば、Functionコンストラクタみたいなものも作れると思います。

ユーザーに拡張性を持たせる

最近のソフトは、プラグインだとかマクロだとか、ユーザーがより高い自由度でカスタマイズできる手段が用意されています。これを、Flashでやってみるというのはどうでしょう?

ユーザーが使える関数をいくつかエクスポートしておくことで準備完了です。ECMAScriptなので、それほどとっつきにくくもないと思います。


以上、紹介と使用例を書いてみました。長くなってしまいました。すいません。

次は、"データ主体の"スクリプトエンジン(言うなれば吉里吉里のKAGみたいなの)とか、DIコンテナとかかなー。その後タスクとかシーンとか。

この記事へのトラックバック

いやー、やってる人はやってますねー(しかもかなり昔から!!)。 http://www.be-interactive.org/index.php?itemid=6 onEnterFrameのVirtualMachineのexecuteメソッドを呼び出して、プログラムカウンタを増加させ...
ネットビジネス用CGI Perl HTML Javascriptの情報サイト
<p>今までこのサイトでは、CGI(Perl)とJavaScriptの話ばかりをしていますが、コンピューターの世界には、いろいろな種類のプログラムがあります。</p> <p>このカテゴリでは、CGI(Perl)にしぼって、ひたすら書いてき...
ちょっと個人的にやってる実験に、BeIntaractiveさんのECMAインタプ...

TrackBack URL:

http://www.be-interactive.org/trackback.php?id=6

この記事へのコメント

breve riassunto giulietta romeo inglese wrote:
Very good site. Thanks:-)
http://albanian.proloma.inf... auto audi nuova
http://albanian.proloma.inf... auto nuova citroen
http://albanian.proloma.inf... prezzo nuova golf
http://albanian.proloma.inf... la nuova italia scientifica
http://albanian.proloma.inf... finanziamento impresa stato
http://albanian.proloma.inf... analisi personaggio romeo e giulietta
http://albanian.proloma.inf... breve riassunto giulietta romeo inglese
http://albanian.proloma.inf... considerazioni romeo giulietta
http://albanian.proloma.inf... descrizione interiore romeo giulietta
http://albanian.proloma.inf... giulietta romeo inglese
http://albanian.proloma.inf... musical romeo giulietta
http://albanian.proloma.inf... quasimodo traduzione romeo giulietta
http://albanian.proloma.inf... riassunto bambino romeo giulietta
http://albanian.proloma.inf... riassunto romanzo romeo giulietta
http://albanian.proloma.inf... ritratto interiore romeo giulietta
http://albanian.proloma.inf... romeo and giulietta and testo
http://albanian.proloma.inf... romeo giulietta analisi dei personaggio
http://albanian.proloma.inf....html
http://albanian.proloma.inf... sintesi romeo giulietta inglese
http://albanian.proloma.inf... testo letterario romeo giulietta

コメント書き込み: