Luaで、エロノベルゲーっぽいものを作ってみようという試みです。
要は、メッセージを表示していて、キーを押すたびに次のメッセージが出てくる、という仕組みです。
そして、ESCキーが押されると即座に終了します。
ESCが押されると即座に終了、という条件が加わると途端に面倒になります。
「表示」と「キー入力待ち」を交互に使うと、「キー入力待ち」すべてにESCチェックが必要になります。
例外を使って上でキャッチしてやるぐらいしか思いつきません。
関数の中で一度returnして、望めばその次の行から再開できる、という仕組みがあれば楽になります。
C#で言えば、yield returnに当たります。
Luaにはコルーチンという形でそれが存在しています。
[test.lua]
function f()
coroutine.yield("ふるいけや")
coroutine.yield("かわずとびこむ")
coroutine.yield("みずのおと")
coroutine.yield("ばしや")
end
function resume()
local res, mes = coroutine.resume(co)
return mes
end
function create()
co = coroutine.create(f)
end
#include "stdafx.h"
#include <lua.hpp>
#include <conio.h>
int _tmain(int argc, _TCHAR* argv[]){
lua_State *L = lua_open();
luaL_openlibs(L);
luaL_dofile(L, "test.lua");
lua_getglobal(L, "create");
if(lua_pcall(L, 0, 0, 0) != 0) {
printf("error : %s\n", lua_tostring(L, -1) );
return 1;
}
for(;;){
int top = lua_gettop(L);
lua_getglobal(L, "resume");
if(lua_pcall(L, 0, 1, 0) != 0) {
printf("error : %s\n", lua_tostring(L, -1) );
return 1;
}
// nilが帰ってきたら終了
if (lua_type(L, -1) == LUA_TNIL) break;
printf("%s\n", lua_tostring(L, -1));
lua_settop(L, top);
//ESC(27)が押されたら終了
if (_getch() == 27) break;
}
lua_close(L);
return 0;
}
まず、coroutine.create()で、コルーチンを生成します。
f()というのが、対象となる関数ですね。
で、生成したコルーチンを引数にcoroutine.resume()を呼ぶと、f()が実行されます。
f()で、coroutine.yield()を呼び出すと、引数を返り値としてreturnします。
以後、resumeが呼ばれると、前回coroutine.yield()が呼ばれた後の行から再開します。
coroutine.resume()の第一返り値はbool型で、コルーチンが継続ならtrue、終了ならfalseになります。
第二返り値以降に、coroutine.yield()の引数が返り値として戻ってきます。
今回は、第二返り値がない(nilが返ってくる)事を利用して終了判定としています。
Luaはテキストファイルでいじれるので、実行ファイルを用意しました。
適当にいじって遊んでください。
[ダウンロード]