Class 有人能给我一些关于Lua中基于组件的实体系统的示例代码吗?

Class 有人能给我一些关于Lua中基于组件的实体系统的示例代码吗?,class,object,lua,entity,components,Class,Object,Lua,Entity,Components,经过长时间的搜索,我决定来这里,因为在互联网上找不到纯粹用Lua编写的基于组件的实体系统 假设我有实体-->“玩家”,它包含健康和行走速度。 这两个“健康”和“行走速度”是否考虑了以后可以在其他对象(例如怪物)中使用的组件本身。我的理解是,组件只是带有方法和属性的常规表,以后可以添加到不同的实体中。如果需要,可以将两个组件添加到一起或合并为一个组件,例如健康组件和耐力组件? 我真正想要的是示例代码,因为我不明白这个系统是如何完全工作的,如何首先创建组件,如何将它们添加到实体中等等。。。 另外,它

经过长时间的搜索,我决定来这里,因为在互联网上找不到纯粹用Lua编写的基于组件的实体系统

假设我有实体-->“玩家”,它包含健康和行走速度。 这两个“健康”和“行走速度”是否考虑了以后可以在其他对象(例如怪物)中使用的组件本身。我的理解是,组件只是带有方法和属性的常规表,以后可以添加到不同的实体中。如果需要,可以将两个组件添加到一起或合并为一个组件,例如健康组件和耐力组件? 我真正想要的是示例代码,因为我不明白这个系统是如何完全工作的,如何首先创建组件,如何将它们添加到实体中等等。。。 另外,它们将如何存储在全局表中或作为模块块存储? 我完全理解OOP和继承在lua中的工作原理,但基于组件的实体系统并没有任何代码示例,只有图片和图表

谢谢:)

这两篇文章:,非常详细地描述了ECS(实体-组件-系统)。
在阅读了它们之后,就可以很容易地在Lua中实现ECS了

“实体”是一个表:键是属于该实体的组件类型名称,值是
true

“组件”只是一个包含一些数据的表,对于某些类型的组件,该表可能为空

您将需要:

  • 全局表“所有组件”:键是组件类型名称,值是子表,其中键是实体ID,值是组件
  • 全局表“所有实体”(键是实体ID,值是实体)
  • 您的
    update()
    函数将由逻辑上有序的“系统”链组成(“系统”是一个代码块,用于对具有特定组件类型组合的组件的所有实体执行某些操作)
向实体添加新组件只是创建组件表并修改所有组件和所有实体中的某些字段


假设我有实体-->“玩家”,它包含健康和行走速度。这两个健康和行走速度组件本身是否考虑过以后可以在其他对象(例如怪物)中使用

组件只是其实体专有的原始数据。
您应该为其他实体创建其他零部件实例

All_Entities = { 
   [100] = { Health = true, Velocity = true, .... },  -- Player
   [101] = { Health = true, Velocity = true, .... },  -- Monster
   ....
}

All_Components = {
   Health = {
      [100] = { max_hp = 42, current_hp = 31 },  -- Player's health
      [101] = { max_hp = 20, current_hp = 20 },  -- Monster's health
      ....
   }, 
   Velocity = {
      [100] = { max_speed = 1.0, speed_x = 0,    speed_y = 0 },  -- Player
      [101] = { max_speed = 2.5, speed_x = -2.5, speed_y = 0 },  -- Monster
      ....
   },
   ....
}

function update(dt)
   ....
   -- "Health system" will act on all entities having "Health" component
   for entity_id, component in pairs(All_Components.Health) do
      -- 5 minutes for full regeneration
      component.current_hp = math.min(
         component.max_hp,
         component.current_hp + component.max_hp * dt / (5*60)
      )
   end
   ....
   -- "Health_Bar system" will traverse over all the entities
   -- having both Health and Health_Bar components simultaneously
   for entity_id, comp_Health_Bar in pairs(All_Components.Health_Bar) do
      local comp_Health = All_Components.Health[entity_id]
      if comp_Health then
         -- entity "entity_id" has two components:
         --    comp_Health and comp_Health_Bar
         -- Now we have all the info needed to draw its health bar
         ....
      end
   end
   ....
end
请注意,这里根本没有OOP,ECS与OOP无关

当然,您可以在这里添加OOP,例如,将相同类型的所有组件视为某个类的实例。但你真的需要它吗?
ECS的理念:“组件”只是原始数据,所有代码都在“系统”内部,这种方式比OOP更灵活


如果需要,可以将两个组件添加到一起或合并为一个组件,例如健康组件和耐力组件


有些“系统”需要这些组件具有不同的类型,因此最好将它们分开。

非常感谢,这非常有用:)我还有一个问题。假设我有一个“健康”组件,它只保存当前健康、最大健康属性,然后是组件“健康”栏,它保存一个3D用户界面元素。现在,“健康”栏组件如何从“健康”组件获取值,并根据“健康”组件值显示健康栏大小。我希望它们是单独的组件“健康”和“健康栏”,因为我不想在每个实体上显示健康栏。您应该添加新的“系统”,它同时遍历所有同时具有健康和健康栏组件的实体。我在答案中添加了“健康酒吧系统”的代码示例。