LoginSignup
12
13

More than 5 years have passed since last update.

AS3.0で少しだけLuaを使えるようにした

Last updated at Posted at 2014-07-10

ないならば作る

ActionScript3.0でゲームを作っているのだけれど、シナリオスクリプトとしてLuaを使いたくなった。
しかし探してみると意外にもなかなかシナリオスクリプトとして使えそうなLua実装がない。
あったかと思うとパーサーのみ公開されていたりすごく特殊な方法で動かす仕組みであったりする。
シナリオスクリプトとして使えればいいので完全な実装は必要ない。
それならなんとかなるかと思い、自分で作ることにした。

作ったもの

いちおうBeefと名づけています。
https://github.com/dotneet/as3-lua

機能

  • Luaソースの実行
  • LuaコードからのAS3.0コードの実行
  • 仮想スレッド(ランタイムが実行コンテキストを共有できる。マルチタスクではない。)
  • Unicode識別子(Lua非互換。日本語を変数や関数名に使用可能)

できないこと

あくまでゲームのシナリオスクリプトとして使えればいいので、実装していない機能が多数あります。
- メタテーブルとかコルーチンとか難しい仕様は実装していません
- ほとんどの標準ライブラリ関数の使用
- if-else/goto以外の制御構文

使い方

1.Luaコードから呼び出す機能の実装(beef.script.SystemFunctionを継承します)

// 指定したミリ秒数分だけスクリプトの実行を停止する関数
public class FuncWaitTime extends SystemFunction {
    public function FuncWaitTime() {
      super();
    }
    public override function call(runtime:ScriptRuntime, params:Vector.<Value>):Value {
      runtime.stop();
      var millis:Number = params[0].asNumber().value;
      setTimeout(function():void{ runtime.resume();}, millis);
      return BooleanValue.TRUE;
    }
  }
}

2. LuaコードからAS3コードを実行

var source:String = "wait_time(1000)";
var c:Compiler = new Compiler();
var fn:ScriptFunction = c.parse(source);
var runtime:ScriptRuntime = new ScriptRuntime();
// wait_timeという名前の関数として登録
runtime.addFunction('wait_time', new FuncWaitTime());
runtime.execute(fn);

今後

開発中のとあるゲーム(非商用)で実際にBeefを使って開発しています。
しばらくスクリプトのバグはでていないのでシナリオスクリプトとして使うくらいならば問題ない安定度にはなっているかなと思います。
機能的なところではforとrepeat構文が未実装というのがかなり痛い感じなので暇があれば実装したいです。

動かせるLuaコードの例

local a = 10
g = a * a + 10
c,d = a,g

a = 1
::ONEMORE::
a = a + 1
print(a)
if a < 10 then goto ONEMORE; end

function 二乗(a)
  print(a * a)
end

二乗(50)
12
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
13