【问题标题】:Lua and C++: separation of dutiesLua 和 C++:职责分离
【发布时间】:2011-02-10 02:16:04
【问题描述】:

请帮助分类组织 C++/Lua 游戏代码的方式并区分它们的职责。最方便的方法是什么,你用哪一种?

例如,Lua 可用于仅初始化 C++ 对象或在每次游戏循环迭代时初始化。它可以仅用于游戏逻辑,也可以用于图形。一些游戏引擎可以完全控制脚本中的所有子系统!我真的不喜欢这种方法(根本没有分离)。

将所有游戏对象(npc、位置)实现为没有 C++ 对象的 Lua 表是个好主意吗?或者最好是镜像它们(控制 C++ 对象的 Lua 表)?还是别的什么?

谢谢。

编辑。我的分类:Lua and C++: separation of duties

话题继续:Lua, game state and game loop

【问题讨论】:

    标签: c++ oop lua modularity lua-c++-connection


    【解决方案1】:

    我的方法是尽可能限制暴露给 Lua 的内容。我从来没有发现每次渲染场景(或更多)时都会调用“主”或其他此类函数。然而,一些 Lua 引擎(如 LOVE)会这样做。我更喜欢为您可能希望对象响应的常见事件(例如碰撞、鼠标点击、进入或离开游戏世界等)定义带有可选回调函数的对象。

    最终结果是非常声明性的,几乎是对象的配置文件。我有一个用于创建对象的类或类型的函数,还有一个用于基于这些类型创建对象的函数。然后,这些对象具有一组方法,可以在响应各种事件时调用这些方法。所有这些 Lua 方法都映射到 C/C++ 方法,这些方法反过来修改对象的私有属性。这是一个可以捕获球对象的桶对象示例:

    define {
        name='ball';
        texture=png('images/orb.png');
        model='active';
        shape='circle';
        radius=16;
        mass=1.0; 
        elastic=.7;
        friction=.4; 
    }
    
    define {
        name='bucket';
        model='active';
        mass=1;
        shape='rect';
        width=60;
        height=52;
        texture=png('images/bucket.png');
        elastic=.5;
        friction=.4; 
        oncontact = function(self, data)
            if data.subject:type() == 'ball' then
                local a = data.subject:angleTo(self:getxy())
                if a < 130 and a > 50 then
                    --update score etc..
                end
            end
        end;
    }
    

    我不会认为这是实现脚本 API 的“一种真正的方式”。 Lua 的优点之一是它支持许多不同风格的 API。这正是我发现的适合我制作的游戏的方法 - 基于 2D 物理的游戏。

    【讨论】:

    • 谢谢,我非常喜欢你的回答。因此,您主要使用 Lua 作为配置文件和回调函数存储库。每个游戏对象都实现为 C++ 对象和 Lua 对象。那是对的吗?你如何同步他们的状态?如何保存游戏 - 生成新的 Lua 配置文件?
    • Lua 对象实际上只是接口,通过单个 lightuserdata 字段映射到 c 中的对象,该字段解析什么是“self”。至于保存,我通常只保存玩家所处的关卡,但我可以实现一个函数,通过简单地获取每个对象的状态,然后编写一个脚本来设置它们,完全在 Lua 中重新创建整个游戏状态——也许不是非常优化,在这种情况下我可能会考虑序列化。
    【解决方案2】:

    我提出这个分类:

    1. 极端变体:Lua 脚本控制一切(游戏逻辑、图形、AI 等)。甚至更多:脚本作为主机程序工作,拥有游戏循环。有些引擎会做这样的事情。坏事:根本没有职责分离,也没有脚本安全。

    2. Lua 脚本维护游戏状态并处理游戏逻辑。可能在每次游戏循环迭代时都会调用脚本。

    3. Lua 脚本很少用于初始化、配置、回调。主机程序为脚本提供(绑定)一个非常简约的界面。所以脚本是由这些精心设计和提供的块构建的。

    【讨论】:

      【解决方案3】:

      从小处着手。允许访问游戏实体,以便您可以执行特定于地图/关卡的脚本。跨地图/关卡一致的行为可能不需要编写脚本。

      另外,只允许访问对象的公共接口。

      【讨论】:

      • 感谢您的第一个回答。比如说,将所有游戏对象(npc、位置)实现为没有 C++ 对象的 Lua 表是个好主意吗?还是镜像它们更好?还是别的什么?
      • 我会用 C++ 实现游戏对象,但用 Lua 实例化它们。在实例化期间,您可以将属性设置为您希望它们针对特定情况的属性。你也可以为你的 Lua 脚本设置回调,例如:如果 door47 被打开然后调用 Lua 函数 xyz。我建议你使用 Lua 作为游戏的“故事”,使用 C++ 作为机制。
      猜你喜欢
      • 1970-01-01
      • 2017-06-11
      • 2022-01-10
      • 2014-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-09
      相关资源
      最近更新 更多