Mô hình hóa các singletons khác trong một hệ thống thành phần


7

Tôi đang viết một triển khai tiểu hành tinh cơ bản như một bài tập trong việc học cách suy nghĩ trong các thực thể và các thành phần, và hầu hết đều khá đơn giản. Nhưng có một điều tôi tiếp tục gặp phải là các tình huống trong đó một hệ thống nhất định cần một thực thể / thành phần nhất định và tôi biết chỉ có một trong số đó. Ví dụ:

  • MovementSystemcần biết giới hạn của Worldthành phần để nó biết khi nào cần bọc sang phía bên kia của màn hình
  • LevelSystemcần biết GameStatethành phần để nó biết có nên tạo ra các tiểu hành tinh mới không
  • InputSystemcần biết trạng thái của Keyboardthành phần

(Vân vân.)

ECS tôi đang sử dụng được cuộn bằng tay nhưng về mặt khái niệm tương tự như Hệ thống thực thể RDBMS Beta - Java của Adam Martin . Những gì tôi thấy mình làm liên tục cho các trường hợp như ở trên là yêu cầu các EntityManagerthành phần "tất cả" của loại đã cho và lấy "đầu tiên" (chỉ gọi là):

World world = entityManager.getAllComponentsOfType(World.class).iterator().next()

Điều này hoạt động nhưng có vẻ lộn xộn, và làm cho mã khó chịu không rõ ràng. Các lựa chọn thay thế mà tôi đã nghĩ đến:

  • làm cho mỗi hệ thống lặp lại 'tất cả' các thành phần này, giống như bất kỳ loại thành phần nào khác
  • thêm hỗ trợ rõ ràng cho các thành phần 'singleton' vào EntityManager
  • không sử dụng các thành phần cho những thứ này; tiêm chúng vào hệ thống theo một cách khác và sống với thực tế rằng điều này làm cho thiết kế kém tinh khiết hơn đáng kể

Có một giải pháp điển hình hoặc nổi tiếng cho vấn đề này?

Câu trả lời:


14

Hãy nhớ không được mang đi với các thực thể và các thành phần. Hoàn toàn ổn khi khôngWorldthành phần của bạn . Nếu bạn biết chắc chắn sẽ chỉ là một trong những thứ gì đó, thì sẽ không có ý nghĩa gì khi biến nó thành một thành phần. Các thành phần được tạo ra để được tái sử dụng trong nhiều thực thể, kết hợp với các thành phần khác.

Điều này không làm cho trò chơi kém tinh khiết hơn, nó làm cho mã sạch hơn. Các hệ thống thực thể chỉ là một công cụ cho một phần trò chơi của bạn, nó không cần phải bao gồm tất cả để trở thành một hệ thống tốt. Chỉ sử dụng nó khi nó có ý nghĩa với bạn .


2
Câu trả lời thực sự tốt. Hãy nhớ vào cuối ngày, nếu bạn không hoàn thành trò chơi của mình, thì sẽ không có ai chơi nó. Làm những gì làm việc để hoàn thành công việc.
wes

4
+1 Chỉ vì bạn có một cái búa không có nghĩa là mọi thứ đều là đinh =)
Patrick Hughes

1

Như những người khác đã nói, singletons không phải được thực hiện như là các thành phần. Lưu trữ dữ liệu đó trực tiếp trong các hệ thống hoặc một số lớp singleton bên ngoài là tốt, miễn là chỉ có các hệ thống đang truy cập nó. Tuy nhiên, nếu bạn thực sự muốn giữ cho thiết kế của mình 'thuần khiết' (nó làm cho việc tuần tự hóa toàn bộ trạng thái trò chơi đơn giản hơn nhiều nếu tất cả dữ liệu nằm trong các thành phần), hãy xem xét sử dụng trực tiếp trường tĩnh hoặc getter trong thành phần, ví dụ: "Thế giới .instance ".


0

Một cách để làm điều đó là triển khai một hệ thống nhắn tin trong ứng dụng của bạn. Sau đó, bạn có thể tạo các sự kiện về việc tạo các thành phần cụ thể.

MovementSystemchỉ có thể đăng ký với người quản lý sự kiện cho sự kiện WorldComponentCreatedEventvà khi bạn tạo thành phần thế giới của mình, MovementSystemsự kiện sẽ nhận được sự kiện có thể tổ chức giới thiệu với thế giới dưới dạng dữ liệu sự kiện.


Một hệ thống nhắn tin là một ý tưởng tốt cho một số thứ, nhưng ở đây, những 'người độc thân' này có lẽ không nên là thành phần trên các thực thể
ThorinII
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.