2017-03-07 52 views
1

經過長時間的搜索,我決定來到這裏,因此無法在互聯網上找到純粹在Lua中編寫的基於組件的實體系統。任何人都可以給我關於基於組件的實體系統在Lua的示例代碼?

比方說,我有實體 - >「球員」,它包含健康和Walkspeed。 這兩個Health和Walkingpeed會考慮組件本身,以後可以用於其他對象,例如Monster。我的理解是,組件只是常規的表格,其中包含可以稍後添加到不同實體的方法和屬性。如果需要,可以將兩個組件添加到組合中,例如健康組件和耐力組件? 我真的想要的是示例代碼,因爲我不明白這個系統將如何完全工作,組件將如何創建在第一位,我怎麼可以將它們添加到實體等... 他們將如何存儲在全局_G表中或作爲模塊塊? 我完全理解如何在lua中使用OOP和繼承,但基於組件的實體系統沒有任何代碼示例,只有圖片和圖表。

謝謝:)

回答

0

這兩篇文章:12詳細描述ECS(實體 - 組件 - 系統)非常好。
閱讀完它們後,很容易在Lua中實施ECS。

「實體」是一個表:鍵是屬於此實體的組件類型名稱,值爲true

「組件」只是包含某些數據的表,對於某些類型的組件,該表可能爲空。

你將需要:

  • 全局表「All_Components」:關鍵是組件類型名稱,值是子表,其中鍵是實體ID,值是組件,
  • 全局表「All_Entities」(鍵是實體ID,值是實體),
  • 您的update()函數將由「系統」的邏輯上有序的鏈組成(「系統」是代碼塊,用於對具有組件的某些特定組合的所有實體執行某些操作的代碼塊類型)。

將新組件添加到實體只是創建組件表並修改All_Components和All_Entities中的某些字段。


可以說我有實體 - > 「播放器」,它包含健康和Walkspeed。這兩個健康和步行者是否會考慮組件本身,以後可以用於其他物體,比如Monster?

組件只是其實體私有的原始數據。
您應該爲另一個實體創建另一個組件實例。

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更靈活。


可以兩種組分可以一起添加或合併的例如衛生成份和耐力組分合爲一體,如果需要的話?

某些「系統」將需要這些組件具有不同類型,因此最好將它們分開。

+0

非常感謝你的這個,這是非常有幫助的:) –

+0

我還有一個問題。假設我擁有僅保存current_health,max_health屬性的「健康」組件,然後保存具有3D用戶界面元素的組件「Health_Bar」,現在「Health_Bar」組件將如何從「健康」組件獲取值並顯示Health_Bar大小,依據「健康「組件值。我希望他們是單獨的組件「健康」和「Health_Bar」,因爲我不想在每個實體上顯示Health_Bar。 –

+0

您應該添加新的「系統」,該系統同時遍歷具有** Health和Health_Bar組件的所有實體。我已將「Health Bar system」的代碼示例添加到答案中。 –

相關問題