Xác định 'Loại' thực thể trong Hệ thống thành phần thực thể


10

Nếu một Thực thể không có 'loại' rõ ràng (ví dụ: trình phát) và chỉ đơn giản là một tập hợp các thành phần, làm cách nào để xác định các thực thể mà hệ thống của tôi nên và không nên hoạt động? Ví dụ, trong một trò chơi của Pông, mái chèo và bóng đều va chạm với các ranh giới cửa sổ. Tuy nhiên, các hệ thống xử lý va chạm cho mỗi hệ thống sẽ khác nhau, do đó một hệ thống không nên xử lý các thực thể sai loại.

void PlayerCollisionSystem::update(std::vector<Entity *> entities) {
  typedef std::vector<Entity *>::iterator EIter;
  for (EIter i = entities.begin(); i != entities.end(); ++i) {
    Entity *player = *i; // How do I verify that the entity is a player?

    // Get relevant components.
    PositionComponent *position = player->getComponent<PositionComponent>();
    VelocityComponent *velocity = player->getComponent<VelocityComponent>();
    SpriteComponent *sprite = player->getComponent<SpriteComponent>();

    // Detect and handle player collisions using the components.
  }
}

Cả người chơi và quả bóng đều có chung các loại thành phần có liên quan để xử lý va chạm nhưng việc triển khai hệ thống của họ sẽ khác nhau.

Nếu tôi có một thùng chứa tất cả các thực thể trò chơi, làm cách nào để xác định các loại thực thể cụ thể mà không kế thừa Entityhoặc bao gồm một biến thành viên std::string type, như trong trường hợp đó, một thực thể không còn đơn giản là một tập hợp các thành phần?

Câu trả lời:


21

Câu trả lời của Nicol Bolas là thẳng thắn, nhưng bước sang một bên và nhìn vấn đề của bạn từ xa: bạn thực sự không cần loại thực thể.

Bạn chỉ cần quan tâm liệu "đối tượng có thành phần X" hay không và vấn đề của bạn là bạn chưa xác định đúng X. Nếu hai đối tượng hành xử khác nhau thì cung cấp cho chúng các thành phần khác nhau hoặc chỉ đặt một cờ boolean trên thành phần đó nếu nó làm cho nó hoạt động khác nhau đối với các cấu hình đối tượng khác nhau. Sử dụng hệ thống thành phần để đưa ra quyết định về hành vi, chứ không phải "loại" thực thể. Đó là toàn bộ quan điểm của việc sử dụng các thành phần.

Bạn hoàn toàn được phép có một PaddlePhysicsthành phần / hệ thống và một BallPhysicsthành phần / hệ thống riêng biệt nếu chúng hoạt động khác nhau. Hoặc bạn có thể chia các thành phần thành nhiều phần nhỏ hơn để bạn có một Bouncethành phần chỉ có Ball và một StopAtBoundarythành phần mà cả hai BallPaddlecó nếu một phần của hành vi đủ phức tạp để biện minh cho việc chia sẻ mã. Hoặc bạn chỉ có thể tạo một PongPhysicsthành phần có cờ boolean Bouncesđược đặt truecho Ballfalsecho Paddle. Bạn thậm chí có thể tạo một WallCollisionthành phần cơ bản và sau đó lấy ra thành phần đó để có được một BallWallCollisionhành vi bổ sung cần thiết ở đó.


4
Tôi nghĩ rằng đây nên là câu trả lời được chấp nhận vì hoàn toàn không có ràng buộc hay vấn đề nào với ECS "vanilla". Các thực thể gắn thẻ có thể được thực hiện dễ dàng bằng cách tạo các thành phần chuyên dụng đóng vai trò là điểm đánh dấu. Nó cũng có thể chỉ là một PlayerTypeComponent giả không làm gì hữu ích mà chỉ phục vụ như một thẻ.
tiguchi

19

Một hệ thống chỉ hữu ích nếu nó hữu ích. Nếu một hệ thống trong đó một thực thể "đơn giản là một bộ sưu tập các thành phần" thì ít hữu ích hơn một hệ thống mà một thực thể chủ yếu là một "bộ sưu tập các thành phần", thì hãy làm điều đó .

Ngừng cố gắng tạo ra các hệ thống "thuần túy" và tập trung vào làm cho các hệ thống tốt làm những gì bạn cần. Sử dụng các thành phần cho đến khi các thành phần không còn hữu ích cho bạn. Sau đó sử dụng một cái gì đó khác.

Bạn đã dành nhiều thời gian suy nghĩ về điều này hơn nó xứng đáng.


rất hay +1 "Bạn đã dành nhiều thời gian suy nghĩ về điều này hơn nó xứng đáng"
wes

8
Tôi không nghĩ đây là một câu trả lời, Chủ đề tinh chỉnh ECS là một vấn đề đáng được quan tâm, và Garee (khi ông đăng bài này vào năm 2013) có lẽ đã không dành đủ thời gian để nghĩ về nó. Quan niệm cho rằng chủ đề không xứng đáng có nhiều thời gian hơn ngụ ý rằng các hệ thống nên đơn giản hoặc tầm thường và nói chung là không quan trọng đối với thời gian của chúng ta. Tôi thích câu trả lời của Sean Middleditch vì nó thực sự cố gắng trả lời câu hỏi thay vì bác bỏ nó.
Gavin Williams

Câu trả lời chính xác. Thỉnh thoảng tôi thấy mình phải nói điều này với chính mình. Tập trung vào việc di chuyển về phía trước.
Đaminh Bou-Samra

5

Nếu bạn muốn cung cấp cho các thực thể một kiểu rõ ràng, cách dễ nhất là xác định một biến loại trong lớp thực thể. Chỉ giữ cho mẫu EC miễn là nó hữu ích.

Mặt khác, loại được ngụ ý thông qua các thuộc tính thành phần. Ví dụ, thành phần vật lý sẽ có một thuộc tính cho thiết bị di động so với văn phòng phẩm. Hệ thống sau đó biết khi nào hai điện thoại di động va chạm (bóng và mái chèo). Tương tự như vậy, bạn có thể có các thuộc tính cho cách hệ thống va chạm sẽ phản ứng. Chỉ dừng lại đối tượng hoặc phản ánh nó? Nhìn vào các thuộc tính sẽ cho bạn một ý tưởng về thực thể là gì, nhưng nó không liên quan. Các hệ thống không cần biết loại thực thể mà chúng đang làm việc là gì, chúng nên được cung cấp đủ thông tin bằng cách sử dụng các thành phần được cung cấp cho chúng.

Cuối cùng, có thể thêm một thành phần bổ sung có chứa một loại, nhưng, như thêm một loại vào thực thể, cuối cùng bạn sẽ viết rất nhiều mã cụ thể loại, đánh bại mục đích của hệ thống EC.


0

Một thực thể là một tập hợp các thành phần. Bạn không thể gán nhãn gọn gàng cho một bộ ngẫu nhiên. Đưa ra các ràng buộc loại là giá cho sự linh hoạt tuyệt vời.

Tất nhiên bạn có thể có các lớp thực thể (đánh máy) đặc biệt áp đặt các hạn chế đối với các thành phần.

Thành phần lý tưởng là độc lập. Vì vậy, giải pháp cho vấn đề của bạn sẽ là gọi xử lý va chạm trên từng thành phần con theo thứ tự. Trong các ứng dụng thực tế có sự phụ thuộc lẫn nhau và các vấn đề đặt hàng. Nếu đó là trường hợp bạn cần một số logic 'người điều phối' trong mọi phương thức của lớp Thực thể.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.