【问题标题】:Running Lua scripts line per line每行运行 Lua 脚本
【发布时间】:2015-03-01 14:56:07
【问题描述】:

我正在制作一款游戏,您可以在游戏中使用 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(),假设它返回false。所以它现在将运行 robot:turn_right(45) 并等待动作完成,因为旋转可能需要 3 秒左右。与 go_forward(0.1) 相同。在继续之前我如何让它等待?

现在我使用lua.DoString(code); 来执行所有代码。问题是它没有等到继续前进。

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

我对 Lua 和 Lua C/C# 库有点陌生,所以我会感谢您提供详细的答案。我不希望有人为我编写代码,只想知道关键命令以及如何构建它。

提前致谢!

【问题讨论】:

  • 一种选择是让机器人类的命令在命令执行之前不返回。 (否则,名称最好像go_forward_async)。
  • 如何在不冻结整个线程的情况下做到这一点?
  • 你说的“等待”不就是这个意思吗?冻结用户的 Lua“执行线程”?
  • 我想我必须在第二个线程上运行 Lua,而不是在主线程上,所以是的,我的错。在 C# 中冻结当前线程的最佳方法是什么?假设我想将其冻结 10 秒。

标签: c# c lua


【解决方案1】:

一个相对简单的解决方案 (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()

【讨论】:

  • 这是个好建议。我想我会选择这样的东西。谢谢你:)
【解决方案2】:

一种选择是让机器人类的命令在命令执行之前不返回。这可能意味着在单独的线程上运行用户的 Lua 状态。如果无法检查是否完成,那么您可以估计时间并使用以下方法:

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

【讨论】:

    猜你喜欢
    • 2016-06-19
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    相关资源
    最近更新 更多