2010-10-18 41 views
7

Tôi đang tạo một component-based game object system. Một số mẹo:Đăng ký thành phần đối tượng trò chơi trong hệ thống con trò chơi? (Thiết kế đối tượng trò chơi dựa trên thành phần)

  1. GameObject chỉ đơn giản là danh sách Components.
  2. GameSubsystems. Ví dụ: kết xuất, vật lý, v.v. Mỗi GameSubsystem chứa các con trỏ đến một số số Components. GameSubsystem là một sự trừu tượng rất mạnh mẽ và linh hoạt: nó đại diện cho bất kỳ slice (hoặc khía cạnh nào) của thế giới game.

Có nhu cầu trong cơ chế đăng ký Components trong GameSubsystems (khi GameObject được tạo và soạn). Có 4 phương pháp tiếp cận:


  • 1: Chain of responsibility mẫu. Mỗi Component được cung cấp cho mọi GameSubsystem. GameSubsystem đưa ra quyết định Components nào để đăng ký (và cách sắp xếp chúng). Ví dụ, GameSubsystemRender có thể đăng ký thành phần Renderable.

pro. Components không biết gì về cách chúng được sử dụng. Khớp nối thấp. A. Chúng tôi có thể thêm GameSubsystem mới. Ví dụ, hãy thêm GameSubsystemTitles đăng ký tất cả ComponentTitle và đảm bảo rằng mỗi tiêu đề là duy nhất và cung cấp giao diện để quering đối tượng theo tiêu đề. Tất nhiên, ComponentTitle không nên được viết lại hoặc thừa hưởng trong trường hợp này. B. Chúng tôi có thể sắp xếp lại GameSubsystems hiện có. Ví dụ, GameSubsystemAudio, GameSubsystemRender, GameSubsystemParticleEmmiter có thể được hợp nhất vào GameSubsystemSpatial (để đặt tất cả âm thanh, emmiter, render Components trong cùng một hệ thống phân cấp và sử dụng các biến đổi tương đối cha mẹ).

con. Kiểm tra từng lần. Rất không hiệu quả.

con. Subsystems biết về Components.


  • 2: Mỗi Subsystem tìm kiếm Components các loại cụ thể.

pro. Hiệu suất tốt hơn so với Approach 1.

con. Subsystems vẫn biết về Components.


  • 3: Component đăng ký chính nó trong GameSubsystem(s). Chúng ta biết tại thời gian biên dịch có một GameSubsystemRenderer, vì vậy hãy ComponentImageRender sẽ gọi một cái gì đó như GameSubsystemRenderer :: register (ComponentRenderBase *).
    Observer mẫu. Component đăng ký sự kiện "cập nhật" (được gửi bởi GameSubsystem(s)).

pro. Hiệu suất.Không có séc không cần thiết như trong Approach 1Approach 2.

con. Components bị kết hợp kém với GameSubsystems.


  • 4: Mediator mẫu. GameState (có chứa GameSubsystems) có thể triển khai registerComponent (Thành phần *).

pro. ComponentsGameSubystems không biết gì về nhau.

con. Trong C++ nó sẽ trông giống như chuyển đổi typeid xấu xí và chậm.


Câu hỏi: phương pháp nào là tốt hơn và chủ yếu được sử dụng trong thiết kế dựa trên thành phần? Thực hành nói gì? Bất kỳ đề xuất nào về triển khai (theo hướng dữ liệu) của Approach 4?

Cảm ơn bạn.

Trả lời

2

Bỏ phiếu cho phương pháp thứ ba.

Tôi hiện đang làm việc trên hệ thống đối tượng trò chơi dựa trên thành phần và tôi thấy rõ một số lợi thế khác của phương pháp này:

  • thành phần này là ngày càng có nhiều tự túc subentity vì nó chỉ phụ thuộc vào một tập hợp các hệ thống phụ có sẵn (tôi cho rằng bộ này được cố định trong dự án của bạn).

  • Thiết kế theo hướng dữ liệu được áp dụng nhiều hơn. Lý tưởng nhất, theo cách này bạn có thể thiết kế một hệ thống mà các thành phần được định nghĩa hoàn toàn trong các điều khoản của dữ liệu chứ không phải C++.


EDIT: Một tính năng tôi nghĩ về khi làm việc trên CBGOS. Đôi khi thuận tiện để có khả năng thiết kế và xây dựng các thành phần thụ động không phụ thuộc. Khi điều này là trong tâm trí của bạn cách tiếp cận thứ tư là cách duy nhất.

+0

Tôi đồng ý với bạn rằng những lợi thế này rất có giá trị. Nhưng cái đầu tiên có một mặt khác: không có khả năng tái sử dụng 'Component' giữa các dự án (với các bộ khác nhau của' Hệ thống con').Việc phân phối các hệ thống con trong một dự án đơn lẻ cũng trở thành một vấn đề. Có thể có hàng trăm thành phần '', viết lại tất cả là một công việc tẻ nhạt. Tôi tin rằng lợi thế thứ hai có thể đạt được trong các cách tiếp cận khác, quá. –

+0

Đồng ý với quan điểm của bạn. Tại một thời điểm tôi được giới thiệu với thiết kế CBGOS không nhiều như tôi muốn. Nhưng công việc tôi gặp phải trong việc giải quyết vấn đề này đã cho tôi những cân nhắc sau: * 1. * Thiết kế các giao diện hệ thống con theo cách trừu tượng nhất để tập hợp các hệ thống phụ sẽ thay đổi một chút giữa các dự án khác nhau. * 2. * Ưu tiên tương tác bằng tin nhắn giữa các thành phần trên tất cả và cắt bỏ các phụ thuộc giao diện trong đó có thể. – Keynslug

+0

Nó có thể hoạt động. Tôi đã gặp mọi người tại các diễn đàn gamedev.net sử dụng cách tiếp cận này. –

1

Cách tiếp cận của tôi là triển khai mẫu proxy trong mỗi hệ thống con. Vì mỗi hệ thống con chỉ quan tâm đến một tập con của tổng số thành phần mà mỗi thực thể có thể chứa, Proxy lưu trữ các con trỏ chỉ với các thành phần mà hệ thống quan tâm, ví dụ, hệ thống chuyển động chỉ quan tâm đến vị trí và vận tốc, vì vậy nó cần một proxy hai con trỏ, cho các thành phần đó. Nếu thực thể thiếu một hoặc nhiều trong số đó, thì hệ thống con sẽ bỏ qua nó. Nếu cả hai thành phần đều có mặt, thì một nút proxy được tạo và thêm vào bộ sưu tập nội bộ. Nó cũng hữu ích cho proxy để lưu trữ giá trị định danh duy nhất cho thực thể, sao cho proxy có thể được thêm vào/gỡ bỏ trong thời gian không đổi từ mỗi hệ thống con, nếu cần thiết.

Theo cách như vậy, nếu một thực thể được yêu cầu phải được loại bỏ khỏi động cơ, một thông báo chứa id của thực thể có thể được gửi đến mọi hệ thống con. Proxy sau đó có thể được loại bỏ khỏi mỗi bộ sưu tập hệ thống con một cách độc lập.

+0

Cách tiếp cận tốt, Ian. –

Các vấn đề liên quan