2011-02-14
Cocos2dへSquirrelを組み込み
RPGに使う敵AIには組み込みスクリプトが必要なんじゃなかろうか?
ということでCocos2dのテンプレートにSquirrelを組込んでみることにしてみた。
ダウンロード&展開
調べてみると3.0 betaが出てるようだ。
ひとまず squirrel_3_0_beta3.tar.gz をダウンロードして使ってみることにする。
ダウンロードしたファイルを解凍すると、以下の画像の様にフォルダのアクセス権がロックされてて中を見る事ができない。
フォルダを選択して Command + i でフォルダ情報を表示し、everyone に読み/書き権限を設定する。このままだと下位のフォルダの権限は変更されないため、下のギアアイコンから「内包している項目に適用」を選択して全てのフォルダ権限を変更する。
これで使用準備完了。
Cocos2dプロジェクトへの組み込み
Cocos2dから生成されるテンプレートのlibsフォルダの下に先ほど展開したSQUIRREL3フォルダをコピーする。
そして、cocos2d Sourcesフォルダ内に新規にSQUIRREL3グループを作成し、更にその中に以下の表の様なグループを作成しファイルをドラッグ&ドロップで追加する。
| グループ名 | コピーするファイル |
| SQUIRREL3/include | libs/SQUIRREL3/include 内の全ファイル |
| SQUIRREL3/squirrel | libs/SQUIRREL3/squirrel 内の全ファイル |
| SQUIRREL3/sqstdlib | libs/SQUIRREL3/sqstdlib 内のsqstdrex_old.cppを除いた全ファイル |
sqstdrex_old.cppを入れておくとコンパイル時にエラーになるので外した。
最後にヘッダファイルの検索パスに libs/SQUIRREL3/include を追加する。
これで組み込みは完了。
Object-CからSquirrelスクリプトの呼び出し
テストするスクリプトはこんなカンジ。
仮に test.nut とでも名付けようか。
function foo(i, f, s)
{
print("Called foo(), i="+i+", f="+f+", s='"+s+"'");
}
ここからはCの実装になる。
最初にVMマシンを生成する。
HSQUIRRELVM v = sq_open(1024); //1024はコールスタックサイズ
続いて、エラーレポートやprintの出力先関数を登録する。
sqstd_seterrorhandlers(v);
sq_setprintfunc(v, printfunc, printfunc); //sets the print function
プリント関数は以下のようになる。
void printfunc(HSQUIRRELVM v, const SQChar *s, ...)
{
va_list arglist;
va_start(arglist, s);
scvprintf(s, arglist);
va_end(arglist);
}
sq_pushroottable(v); sqstd_dofile(v, "test.nut", 0);
読み込みに成功したら、スクリプト内関数のfoo()を呼出してみよう。
void call_foo(HSQUIRRELVM v, int n,float f,const SQChar *s) { int top = sq_gettop(v); //saves the stack size before the call sq_pushroottable(v); //pushes the global table sq_pushstring(v,_SC("foo"),-1); if(SQ_SUCCEEDED(sq_get(v,-2))) { //gets the field 'foo' from the global table sq_pushroottable(v); //push the 'this' (in this case is the global table) sq_pushinteger(v,n); sq_pushfloat(v,f); sq_pushstring(v,s,-1); sq_call(v,4,0); //calls the function } sq_settop(v,top); //restores the original stack size }
かなり端折って説明してしまったので、より詳細な解説を知りたい人は以下の資料を参考にしてみてください。
SquirrelスクリプトからC関数の呼び出し
、、、眠いので詳細は後ほど。
SquirrelとPythonの比較
組み込みスクリプトの候補としてPythonも考えたがソースコード量が多い点がネックとなり、今回は見送りました。
| 種類 | コードサイズ |
| Python | ヘッダ+ソースで2MB程度 |
| Squirrel | ヘッダ+ソースで500KB程度 |
2MBもあったらゲーム本体のソースより多くなりそうな気がする。。。
組み込み済みのプロジェクト
今回の説明のためにCocos2dのテンプレートにSquirrelを組込んでみたサンプル。
HelloWorldScene.mの-(id) initからtest.nutをロードしてfoo()関数を呼出しています。
https://files.me.com/penguin.dream/pzk5zm
※リンクは3ヶ月間のみ有効です。






