Chúng tôi bắt đầu từ cách tiếp cận hệ thống-thành phần-thực thể cơ bản .
Hãy tạo tập hợp (hạn có nguồn gốc từ này bài viết) chỉ ra các thông tin về các loại linh kiện . Nó được thực hiện một cách linh hoạt trong thời gian chạy, giống như chúng ta sẽ thêm / xóa từng thành phần cho từng thực thể, nhưng hãy đặt tên chính xác hơn vì nó chỉ là về thông tin loại.
Sau đó, chúng tôi xây dựng các thực thể chỉ định tập hợp cho mỗi người trong số họ. Khi chúng ta tạo thực thể, tập hợp của nó là bất biến, điều đó có nghĩa là chúng ta không thể trực tiếp sửa đổi nó tại chỗ, nhưng chúng ta vẫn có thể lấy chữ ký của thực thể hiện tại thành một bản sao cục bộ (cùng với nội dung), thực hiện các thay đổi phù hợp với nó và tạo ra một thực thể mới của nó
Bây giờ đối với khái niệm khóa: bất cứ khi nào một thực thể được tạo, nó được gán cho một đối tượng được gọi là nhóm tập hợp , có nghĩa là tất cả các thực thể có cùng chữ ký sẽ nằm trong cùng một thùng chứa (ví dụ: trong std :: vector).
Bây giờ các hệ thống chỉ lặp đi lặp lại qua mỗi nhóm lợi ích của họ và thực hiện công việc của họ.
Cách tiếp cận này có một số ưu điểm:
- các thành phần được lưu trữ trong một vài (chính xác: số lượng thùng) khối bộ nhớ liền kề - điều này giúp cải thiện sự thân thiện với bộ nhớ và dễ dàng hơn trong việc loại bỏ toàn bộ trạng thái trò chơi
- hệ thống xử lý các thành phần theo cách tuyến tính, có nghĩa là sự kết hợp bộ nhớ cache được cải thiện - tạm biệt từ điển và nhảy bộ nhớ ngẫu nhiên
- tạo một thực thể mới dễ dàng như ánh xạ tập hợp vào nhóm và đẩy lùi các thành phần cần thiết vào vector của nó
- xóa một thực thể dễ dàng như một cuộc gọi đến std :: di chuyển để trao đổi phần tử cuối cùng với phần tử bị xóa, bởi vì thứ tự không quan trọng tại thời điểm này
Nếu chúng ta có nhiều thực thể có chữ ký hoàn toàn khác nhau, lợi ích của loại kết hợp bộ nhớ cache giảm dần, nhưng tôi không nghĩ rằng nó sẽ xảy ra trong hầu hết các ứng dụng.
Ngoài ra còn có một vấn đề với việc vô hiệu hóa con trỏ một khi các vectơ được phân bổ lại - điều này có thể được giải quyết bằng cách giới thiệu một cấu trúc như:
struct assemblage_bucket {
struct entity_watcher {
assemblage_bucket* owner;
entity_id real_index_in_vector;
};
std::unordered_map<entity_id, std::vector<entity_watcher*>> subscribers;
//...
};
Vì vậy, bất cứ khi nào vì một lý do nào đó trong logic trò chơi của chúng tôi, chúng tôi muốn theo dõi một thực thể mới được tạo, bên trong nhóm chúng tôi đăng ký một entity_watcher và một khi thực thể đó phải là std :: move'd trong khi gỡ bỏ, chúng tôi sẽ tra cứu người theo dõi và cập nhật real_index_in_vector
giá trị mới của họ . Hầu hết thời gian này chỉ áp dụng một tra cứu từ điển cho mỗi lần xóa thực thể.
Có bất kỳ nhược điểm hơn cho phương pháp này?
Tại sao giải pháp không được đề cập đến, mặc dù khá rõ ràng?
EDIT : Tôi đang chỉnh sửa câu hỏi để "trả lời câu trả lời", vì ý kiến không đủ.
bạn mất đi tính chất động của các thành phần có thể cắm được, được tạo ra đặc biệt để thoát khỏi việc xây dựng lớp tĩnh.
Tôi không. Có lẽ tôi đã không giải thích nó đủ rõ ràng:
auto signature = world.get_signature(entity_id); // this would just return entity_id.bucket_owner->bucket_signature or so
signature.add(foo_component);
signature.remove(bar_component);
world.delete_entity(entity_id); // entity_id would hold information about its bucket owner
world.create_entity(signature); // automatically assigns new entity to an existing or a new bucket
Nó đơn giản như chỉ cần lấy chữ ký của thực thể hiện có, sửa đổi nó và tải lên lại như một thực thể mới. Bản chất tự nhiên, năng động ? Tất nhiên. Ở đây tôi muốn nhấn mạnh rằng chỉ có một lớp "tập hợp" và một lớp "xô". Các thùng được điều khiển dữ liệu và được tạo trong thời gian chạy với số lượng tối ưu.
bạn cần phải đi qua tất cả các nhóm có thể chứa mục tiêu hợp lệ. Không có cấu trúc dữ liệu ngoài, việc phát hiện va chạm có thể khó khăn như nhau.
Vâng, đây là lý do tại sao chúng ta có các cấu trúc dữ liệu bên ngoài đã nói ở trên . Cách giải quyết đơn giản như giới thiệu một trình vòng lặp trong lớp Hệ thống phát hiện khi nào nên nhảy sang nhóm tiếp theo. Việc nhảy sẽ hoàn toàn trong suốt theo logic.