【问题标题】:Finite State Machine in Lua and C++Lua 和 C++ 中的有限状态机
【发布时间】:2013-07-26 12:57:15
【问题描述】:

我想在 Lua 中创建 FSM(使用 Luabind)。假设我有 GameObject,在 lua 文件中我确实写了这个:

State1 = {}
State1["Start"] = function()
end
State1["Update"] = function()
    if (blah blah blah) then
        ChangeState(State2);
    end
end
State1["End"] = function()
end
... then states 2, 3 and etc...
gameObject.fsm = CreateFSMComponent(name, State1);

问题是 - 如何创建具有不同属性的相同对象行为?就像..如果我想创建 2 个具有相同行为的巡逻单位,但每个巡逻单位都有不同的起始位置。 但是在 Lua 中——当我定义外部函数来描述其中的这些状态时——它不起作用。

【问题讨论】:

  • 我认为您正在寻找一种将当前状态与其所附加的游戏对象相关联的方法。

标签: c++ lua luabind


【解决方案1】:

您是否在问如何创建两个处于相同状态(行为)但具有不同属性(如起始位置)的对象。如果是这样,您可以采用任何一种函数式方法,假设状态仅表示对您的对象(如 PatrolUnits)进行操作的一系列函数,例如:

PatrolState = {}

PatrolState.Start = function(unit)
    if(SomeChecker(unit.startPos)) then
        DoSomething() -- like unit.curPos = unit.startPos, for example            
    end
end

PatrolState.Update = function(unit)
    if(IsNearSomething(unit.curPos)) then
        DoSomethingElse() -- like ChangeState(State2)
    end
end

,或面向对象的方法。在这种情况下,您必须创建 type State1,2 ... 的对象并将它们保留在周围,这样您就可以在状态对象中保存诸如 startPos 之类的属性。有关如何结帐的更多信息this tutorial

我更喜欢前者,因为美国保持“纯净”并且不保存单位的属性。但这只是风格问题。

-arun

编辑:如果您的单位的位置根据其值具有特殊含义,则可以将逻辑嵌入到状态机代码中:

PatrolState.Update = function(unit)
    if(InsideDeathCircle(unit.position)) then
        ChangeState (KillUnitState)
    end
end

【讨论】:

  • 感谢您的回答,但是如果 unit 没有 startPos 属性怎么办?我的意思是 - 单元可能有位置组件(用 C++ 编写),但是 startPos 或 deathPos 或 smth - 与逻辑相关的参数。是否有必要在 c++ 组件中拥有所有类型的属性?我觉得很糟糕。我应该如何保留(并传递给函数)这些可选属性
  • 我把我的答案改成了你的问题。一般来说,如果你认为某些东西确实是单位的属性——比如位置、计数等——我看不到任何将它们添加为属性的东西。但是如果它们是实际的逻辑,你可以让 Lua 在状态下运行。如果您对这种设计不满意,并且觉得向 Lua 状态添加属性更直观,您始终可以将状态作为类并将状态类型的唯一对象关联到您的单元。我在答案中发布的有关 Lua 中面向对象开发的链接有更多关于此的信息。
猜你喜欢
  • 1970-01-01
  • 2015-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多