+2

Hiểu biết cơ bản về hệ thống Component - Entity - Systems

Một cách truyền thống để xây dựng một game là sử dụng lập trình hướng đối tượng(OOP). Mỗi thực thể trong game là một đối tượng(Object), được tạo ra từ khuôn mẫu lớp(class) cho phép mở rộng thực thể qua tính đa hình. OOP khá hiệu quả đối với những game cỡ nhỏ có ít đối tượng trong game. Khi game lớn có nhiều đối tượng, mỗi đối tượng có nhiều chức năng, đặc điểm khác nhau việc áp dụng OOP sẽ dẫn tới một nhược điểm rất lớn. Đó là khi bạn cần thay đổi 1 đối tượng nào đó sẽ kéo theo một loạt các đối tượng liên quan phải thay đổi theo, điều này làm mất nhiều thời gian và khó tránh khỏi việc bỏ quên update đối tượng liên quan nào đó. Trong phát triển game việc phải thay đổi đối tượng nào đó sẽ thường xuyên xảy ra theo thời gian.

Để giải quyết vấn để này, hệ thống Component - Entity - Systems ra đời. Các lập trình viên bắt đầu xây dựng các đối tượng thông qua các thành phần(component) thay vì kế thừa từ một đối tượng gốc(base object) . Điều này mang lại những lợi ích lớn so với lập trình hướng đối tượng OOP : Dễ dàng để thêm 1 thực thể phức tạp mới. Dễ dàng để mở rộng một thực thể mới bằng cách thêm mới các thành phần của chúng. Dễ dàng sửa lỗi, bảo trì và nâng cấp. Mỗi component sẽ có một chức năng riêng biệt và không lặp lại. Do đó ta dễ dàng khoanh vùng chức năng nào còn thiếu sót để hoàn thiện nó.

Mô hình Component - Entity - Systems

1.Component

Mỗi component giống như một cấu trúc dữ liệu struct. Nó không có phương thức chỉ có khả năng chứa dữ liệu. Các component là độc lập với nhau. Để quản lý tập trung các component thành danh sách trong entity thì các component phải có 1 điểm chung là cùng kế thừa từ một asbtract component. Và component là đối tượng nhỏ nhất để tạo nên entity.

Ví dụ :

Position (x, y) Velocity (x, y) Physics (body) Sprite (images, animations) Health (value) Character (name, level) Player (empty)

2.Entity

Tất cả đối tượng trong game đều là những thực thể (entity), và mỗi thực thể là duy nhất (có một UniqueID).Một entiy là tập hợp nhiều component có cùng UniqueID. Và những đặc điểm (property), trạng thái (state), phản ứng (behaviour) của các entity được quyết định bởi các Component.

Ví dụ:

  • Con monster là một entity, nó được “tổng hợp” bởi : thành phần hiển thị (Renderable), có khả năng di chuyển (Movable), có yếu tố vật lý (Collier, Body), AI nếu cần (AutoMoving)
  • Cái cây bên đường cũng là entity, nó bao gồm : Thành phần hiển thị (Renderable), yếu tố vật lý (Collider, Body), và không có yếu tố về di chuyển (Movable) và AI.

3.System

Là những những module con, hoạt động độc lập nhau, xử lý một “behaviour” nào đó trong game. Như đã nói ở trên các component chỉ chứa dữ liệu và không có phương thức gì. Để một thực thể có khả năng di chuyển công việc đó được thực hiện bởi system. Điều đó có nghĩa là mỗi component sẽ có một system để thực hiện hành vi của nó.

Ví dụ :

  • RenderSystem : nhiệm vụ là “vẽ” tất cả entity có RenderableComponent.
  • MovingSystem : tính toán thông tin vị trí của các entity có MovableComponent.
  • PhysicSystem : kiểm tra va chạm của các entity có ColliderComponent. Trong mỗi vòng lặp update() thì các system sẽ loop qua tất cả các entity có chứa component mà system thực hiện hành vi và update các component đó.

Tổng kết

Component - Entity - System(CES) là một phương pháp lập trình rất hay, đáng để tìm hiểu và sử dụng. Các dự án lớn và đa phần các Game engine, framework đều được hiện thực bằng phương pháp này để tăng tính dễ bảo trì và nâng cấp. Tuy nhiên nó cũng có một số nhược điểm mà chúng ta cần phải lưu ý :

  • Phí tổn cho các System : Như các bạn biết, trong vòng Update(), các System sẽ phải loop qua tất cả các Entity và Update cho các Component, chi phí cho việc này sẽ tăng cao khi số lượng các Component và System nhiều lên. Tất nhiên người ta cũng đã có giải pháp khác phục, đó là lập các Group. Các System sẽ chỉ loop qua các entiy chứa các component mà system đó “lo”, việc nhóm các entity đó lại gọi là tạo các Group. Ngoài ra còn có các giải pháp sâu hơn cho PhysicSystem, RenderSystem – những system chính và “ngốn” performance nhất.

  • Liên lạc giữa các System: Các system không phải lúc nào cũng độc lập hoàn toàn với nhau, có những system cần phải nhận thông tin từ system khác. VD: khi một monster entity bị chết, thì UISystem cần biết để cập nhận thông tin UI chẳng hạn. Người ta giải quyết vấn đề này bằng ObserverPattern.

Qua bài viết này tôi muốn gửi tới các bạn cách nhìn tổng quát về CES hy vọng giúp các bạn có thể áp dụng vào trong công việc lập trình game của mình.

Bài viết có sự tham khảo :

https://www.gamedev.net/articles/programming/general-and-gameplay-programming/understanding-component-entity-systems-r3013/

https://en.wikipedia.org/wiki/Entity–component–system


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí