2015-01-03 57 views
0

我正在制作一个游戏,在游戏中使用Lua编写自己的机器人。我使用名为NLua的C#Lua库,它基本上像官方C库一样工作。每行运行Lua脚本行

如果用户输入下面的代码:

for i=0,10 do -- Repeat 10 times 
    if (robot:check_clear(0.1)) then -- Check if clear up to 10cm in front 
     robot:go_foward(0.1) -- Go foward 10cm 
    else then 
     robot:turn_right(45) -- Turn 45 degrees 
    end 
end 

我希望它运行整个代码10倍,你可以看到。它将继续检查robot:check_clear(),假设它返回false。所以它现在将运行机器人:turn_right(45)并等待该动作完成,因为旋转可能需要3秒左右。与go_forward(0.1)一样。在继续之前,我该如何等待?

现在我用lua.DoString(code);来执行所有的代码。问题在于,在继续之前,它不会等待。

机器人在代码中指的是一个C#类,我称之为LRobot。它是这样分配的lua["robot"] = new LRobot();

我对Lua和Lua C/C#库有点新意,所以我会很感谢你的详细解答。我不想让别人为我编写代码,只想知道关键命令以及如何构造它们。

在此先感谢!

+1

一种选择是将有机器人类的命令不直到执行命令为止。 (否则,名称可能会更像'go_forward_async')。 –

+0

我会怎么做,而不冻结整个线程? –

+1

这不就是你所说的“等”吗?冻结用户的Lua“执行线程”? –

回答

3

一个相对简单的解决方案(IMO)是与协同程序去做。最终,你的代码看起来像:

robot:go_foward(0.1) 
wait_till_robot_stops() 
robot:turn_left() 
wait_till_robot_stops() 
robot:go_foward(0.1) 
wait_till_robot_stops() 
alert("I'm home!") 

的“wait_till_robot_stops()”将直到机器人休息冻结你的函数。如何实现这一点?这很容易。这个wait()函数只是对coroutine.yield()的调用。这会使你的功能(你的协同程序)进入睡眠状态。

现在,你如何唤醒你的协同程序?这很容易。当机器人运动停止时,你的游戏应该在Lua端调用一些函数。我们称之为on_robot_stop()。该函数将调用休眠协程上的coroutine.resume()。

以后,您可以让你的系统有点复杂(但更有趣)由具有的wait()函数等待某些事件:

robot:go_foward(4) 
wait_for("robot rests") 
robot:go_foward(2) 
wait_for("incomming missile") 
robot:raise_shield() 
+0

这是一个很好的建议。我想我会像这样做。谢谢 :) –

1

一种选择是让机器人类的命令不会返回,直到命令执行完毕。这可能意味着在单独的线程上运行用户的Lua状态。如果不能检查完成,那么你可以估算的时间和使用的东西,如:

System.Threading.Thread.Sleep(TimeSpan.FromSeconds(10));