每行运行 Lua 行脚本
Running Lua scripts line per line
我正在制作一款游戏,您可以在游戏中使用 Lua 编写自己的机器人代码。我正在使用名为 NLua 的 C# Lua 库,它基本上就像官方 C 库一样工作。
如果用户输入以下代码:
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(),假设它 returns 为假。所以它现在将运行 robot:turn_right(45) 并等待操作完成,因为旋转可能需要 3 秒左右。与 go_forward(0.1) 相同。在继续之前我如何让它等待?
现在我使用 lua.DoString(code);
来执行所有代码。问题是它在继续之前不会等待。
代码中的robot指的是一个C#class我叫LRobot。它是通过这样做分配的 lua["robot"] = new LRobot();
我是 Lua 和 Lua C/C# 库的新手,所以非常感谢您提供详细的答案。我不想让别人为我编写代码,只是想知道关键命令以及如何构建它。
提前致谢!
一种选择是让机器人 class 的命令在执行命令之前不 return。这可能意味着 运行 用户的 Lua 状态在单独的线程上。如果无法检查是否完成,那么您可以估计时间并使用类似的东西:
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(10));
一个相对简单的解决方案 (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()
我正在制作一款游戏,您可以在游戏中使用 Lua 编写自己的机器人代码。我正在使用名为 NLua 的 C# Lua 库,它基本上就像官方 C 库一样工作。
如果用户输入以下代码:
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(),假设它 returns 为假。所以它现在将运行 robot:turn_right(45) 并等待操作完成,因为旋转可能需要 3 秒左右。与 go_forward(0.1) 相同。在继续之前我如何让它等待?
现在我使用 lua.DoString(code);
来执行所有代码。问题是它在继续之前不会等待。
代码中的robot指的是一个C#class我叫LRobot。它是通过这样做分配的 lua["robot"] = new LRobot();
我是 Lua 和 Lua C/C# 库的新手,所以非常感谢您提供详细的答案。我不想让别人为我编写代码,只是想知道关键命令以及如何构建它。
提前致谢!
一种选择是让机器人 class 的命令在执行命令之前不 return。这可能意味着 运行 用户的 Lua 状态在单独的线程上。如果无法检查是否完成,那么您可以估计时间并使用类似的东西:
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(10));
一个相对简单的解决方案 (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()