Nhiều nguồn chuyển động trong một hệ thống thực thể


9

Tôi còn khá mới với ý tưởng về các hệ thống thực thể, đã đọc rất nhiều thứ (hữu ích nhất, blog tuyệt vời nàycâu trả lời này ).

Mặc dù tôi có một chút khó khăn để hiểu làm thế nào một cái gì đó đơn giản như có thể điều khiển vị trí của một đối tượng bằng một số nguồn không xác định.

Đó là, tôi có thực thể của mình, có một thành phần vị trí. Sau đó tôi có một số sự kiện trong trò chơi bảo thực thể này di chuyển một khoảng cách nhất định, trong một thời gian nhất định.

Những sự kiện này có thể xảy ra bất cứ lúc nào và sẽ có các giá trị khác nhau cho vị trí và thời gian. Kết quả là chúng sẽ được ghép lại với nhau.

Trong một giải pháp OO truyền thống, tôi có một loại MoveBylớp, chứa khoảng cách / thời gian và một mảng những thứ bên trong lớp đối tượng trò chơi của tôi. Mỗi khung hình, tôi sẽ lặp qua tất cả MoveByvà áp dụng nó vào vị trí. Nếu a MoveByđã đạt đến thời gian kết thúc, loại bỏ nó khỏi mảng.

Với hệ thống thực thể, tôi hơi bối rối khi tôi nên sao chép loại hành vi này.

Nếu chỉ có một trong số chúng tại một thời điểm, thay vì có thể kết hợp chúng lại với nhau, thì nó khá đơn giản (tôi tin) và trông giống như thế này:

PositionComponent chứa x, y

MoveByComponent chứa x, y, time

Entitytrong đó có cả a PositionComponentvà aMoveByComponent

MoveBySystemrằng ngoại hình cho một thực thể với cả các thành phần này, và cho biết thêm giá trị của MoveByComponentđể PositionComponent. Khi timeđạt được, nó sẽ loại bỏ thành phần khỏi thực thể đó.

Tôi hơi bối rối về cách tôi làm điều tương tự với nhiều lần di chuyển.

Suy nghĩ ban đầu của tôi là tôi sẽ có:

PositionComponent, MoveByComponentgiống như trên

MoveByCollectionComponenttrong đó có một mảng MoveByComponents

MoveByCollectionSystemtìm kiếm một thực thể có a PositionComponentvà a MoveByCollectionComponent, lặp qua các MoveByComponents bên trong nó, áp dụng / loại bỏ khi cần thiết.

Tôi đoán đây là một vấn đề tổng quát hơn, có nhiều thành phần giống nhau và muốn một hệ thống tương ứng hoạt động trên từng cái. Các thực thể của tôi chứa các thành phần của chúng bên trong hàm băm của loại thành phần -> thành phần, do đó, chỉ có 1 thành phần của một loại cụ thể cho mỗi thực thể.

  1. Đây có phải là cách đúng đắn để được nhìn vào điều này?

  2. Một thực thể chỉ nên có một thành phần của một loại nhất định tại mọi thời điểm?


1
Âm thanh giống như MoveBychức năng chỉ là một vận tốc? Có vẻ như bạn đang đi đúng hướng. Đối với câu hỏi thứ hai của bạn, có rất nhiều triển khai khác nhau của các hệ thống thực thể / thành phần. Một mô tả trong câu trả lời của tôi mà bạn liên kết sẽ chỉ có một thành phần của một loại nhất định.
MichaelHouse

Sắp xếp, nhưng sự khác biệt là vận tốc này chỉ có giá trị từ lần này sang lần khác, và nhiều trong số chúng có thể được gộp lại cùng một lúc. Tôi nghĩ rằng tôi chỉ cần một chút trấn an, tôi đã nghiêm khắc (hậu môn, gần như) OO cho các trò chơi của tôi trong quá khứ - mà những năm sau đó trong cùng một dự án, đã làm tê liệt tốc độ sản xuất của chúng tôi - và đây là lãnh thổ xa lạ;) . Nhân tiện, câu trả lời tuyệt vời trên bài đăng khác, đã giúp làm sáng tỏ một số điều
Chú ý

Tôi làm như thế này: Tôi có PlayerInputComponent và AIInputComponent (hoặc các hệ thống) sẽ thông báo cho MobileBehaviorComponent rằng khi nhấp vào bàn phím hoặc trên AI nghĩ rằng thiết bị di động sẽ di chuyển ở đâu đó, MobileBehaviorComponent sẽ lưu trữ rằng nó sẽ di chuyển ở đâu đó và một số hệ thống sẽ di chuyển nó. Độ chi tiết của bạn quá nhiều, với các thành phần cấp cao hơn, như Transform, Model, Light, Mob mọi thứ đều hoạt động tốt. Ngoài ra tôi không bao giờ cần phải loại bỏ các thành phần - tôi nghĩ về chúng giống như một cái gì đó mô tả đối tượng trò chơi để nó không thể biến mất.
Kikaimaru

Ví dụ MoveBy cụ thể này chỉ là một ví dụ. Câu hỏi là về cách bạn kết hợp mọi thứ lại với nhau như thế. Nếu tôi cần nói cụ thể 'di chuyển bằng x = 5 và y = 6 trong 5 giây' 'di chuyển bằng x = 10 y = 2 trong 10 giây', đồng thời, đây có phải là cách tôi sẽ làm không?
Dính

Bạn có ý nghĩa gì bởi "gộp chung"? Giống như thêm vận tốc? Vì vậy, nếu bạn gộp move x by 10 in 2 secondsmove x by -10 in 2 secondsthực thể sẽ đứng yên hoàn toàn?
Tom Dalling

Câu trả lời:


6

Đối với kịch bản của bạn, chúng tôi thường thêm ba thành phần vào đối tượng trò chơi:

  1. TransformComponent (vị trí, định hướng, tỷ lệ)
  2. VelocityComponent (tốc độ, hướng)
  3. Bộ điều khiển

Khi các đối tượng trò chơi cần một số loại chức năng AI như di chuyển dọc theo một đường dẫn như bạn mô tả, chúng tôi gán AIContler cho danh sách các thành phần của nó. AIControllers thực sự không có gì khác ngoài một trình bao bọc bước một Cây Hành vi. Cây hành vi là nơi chúng ta thiết kế các chức năng thực tế mà chúng ta muốn để đối tượng trò chơi thực hiện, chẳng hạn như:

BehaviorTree* tree(new SequentialNode());
tree->addChild(new MoveToNode(x,y,z));
tree->addChild(new WaitNode(30));
tree->addChild(new MoveToNode(a,b,c));
tree->addChild(new WaitNode(30));
gameObject->addComponent(new AIController(tree));

Hệ thống con AI quản lý AIControllers và do đó hệ thống con đánh dấu vào bộ điều khiển, lần lượt bước vào Cây hành vi. MoveToNode () xem vị trí / hướng hiện tại, tính toán vectơ chỉ hướng và tốc độ đến nơi bạn muốn di chuyển dựa trên các đối số của hàm tạo và đặt các giá trị trên thành phần vận tốc. Hệ thống chuyển động chịu trách nhiệm đọc các thành phần chuyển động với các giá trị và áp dụng vật lý do đó cập nhật vị trí / hướng phù hợp.

Đoạn mã trên chỉ đơn giản là di chuyển một đối tượng trò chơi từ vị trí sinh sản sang x, y, z trong không gian thế giới, sau đó đợi tối thiểu 30 giây, sau đó di chuyển đối tượng trò chơi sang vị trí a, b, c và sau đó đợi thêm 30 giây. Khi chờ đợi kết thúc, chuỗi hành vi đã kết thúc, vì vậy nó lặp lại từ đầu.

Điều này cho phép bạn dễ dàng xác định bất kỳ chức năng AI nào bạn cần có trong hệ thống con AI với tác động tối thiểu đến hệ thống con Thực thể của bạn. Nó cũng cho phép bạn giữ danh sách thành phần hệ thống thực thể của bạn nạc mà không có quá nhiều chi tiết.


1

Một tùy chọn là thêm bộ điều khiển vào thiết kế của bạn. Các thực thể sở hữu dữ liệu để biểu thị vị trí (trong trường hợp động cơ của tôi, chúng cũng có dữ liệu nhớ các vị trí trước đó, vì vậy tôi có thể biết vectơ vận tốc và nếu chúng đang được di chuyển hoặc dịch chuyển tức thời), nhưng chúng không biết gì về vật lý hoặc AI. Bộ điều khiển di chuyển các thực thể và bạn có thể có nhiều bộ điều khiển ảnh hưởng đến cùng một thực thể hoặc một bộ điều khiển ảnh hưởng đến các thực thể khác nhau.

Ví dụ: tạo một lớp Trình điều khiển cơ sở với phương thức run () hoặc nếu bạn không thích tên gọi thì hãy nghĩ (), update () hoặc tick (). Sau đó, bạn kế thừa từ nó và tạo MoveContoder, NPCControll, PlayerInputControll (cho thực thể người chơi), PhysicControll; sau đó bạn thực hiện phương thức run (). Tôi sẽ đặt MoveByComponent của bạn trong MoveContoder chứ không phải trong Thực thể.

Các Bộ điều khiển này có thể được khởi tạo bởi mỗi Thực thể nếu chúng chứa dữ liệu cụ thể của một Thực thể. Chúng có thể bị phá hủy hoặc đặt lại để sử dụng lại sau này. Ngoài ra, bạn có thể sử dụng Bộ điều khiển để di chuyển một nhóm thực thể, ví dụ trong trò chơi RTE, nếu bạn cần di chuyển nhiều đơn vị khác nhau thành một nhóm, mỗi bộ phận có thể điều khiển hiệu suất trò chơi, thì bạn có thể chỉ định tất cả các đơn vị đến GroupContoder hoặc LegionControll và cho phép nó di chuyển các đơn vị như một phần của một nhóm có tổ chức. Khi chiến đấu, nếu trò chơi cho phép hành vi của từng đơn vị riêng lẻ và có lẽ hầu hết các trò chơi đều làm như vậy, bạn sẽ phải chuyển sang Đơn vị điều khiển nhưng tốt hơn là chỉ làm điều đó khi cần thiết hơn từ đầu.

Trong trò chơi đang phát triển của tôi, tôi có một MoveContoder di chuyển các thực thể theo một đường dẫn, một MoveContoder tồn tại cho mỗi NPC và nhân vật người chơi. Đôi khi một cái được tạo ra cho các hộp hoặc đá mà người chơi có thể đẩy. PhysicControll, chỉ một trường hợp, sẽ kiểm tra vị trí của tất cả các thực thể được gán cho nó, nếu một thực thể nào đó đang va chạm với một thực thể được gán khác, vị trí kết quả của cả hai được tính toán (thực tế nó còn hơn thế nhưng bạn hiểu ý). NPCControll là AI, một thể hiện cho mỗi NPC. Nó kiểm tra tình hình của NPC và quyết định nơi sẽ di chuyển, sau đó đẩy đường dẫn đến MoveContoder, thực sự di chuyển NPC. Bộ điều khiển có mức độ ưu tiên, vì vậy tôi có thể xác định trước thứ tự của chúng, PhysicControll là bộ cuối cùng thực thi.

Tôi ủng hộ các bộ điều khiển nhưng không phải là lựa chọn "chính xác" duy nhất. Ví dụ: tôi nhớ một giao diện Thực thể trong công cụ Cafu có phương thức think () trong chính Thực thể, người dùng của lớp phải kế thừa từ Thực thể và triển khai think (), tôi nhớ một lớp dẫn xuất có tên CompanyBot (đi kèm với ví dụ trò chơi) thực hiện một số kiểm tra va chạm trong phương thức đó, vì nó được gọi là "think", chúng ta có thể giả sử mã AI dự kiến ​​cũng sẽ ở đó. Trong khi công cụ NeoAxis (lần trước tôi nhìn vào nó) có AI và vật lý tách biệt với các thực thể.

Có tồn tại một mẫu Trình điều khiển mà tôi đã nghe. Có lẽ bạn nên tìm kiếm nó và có lẽ đó không chính xác là những gì tôi đang nói ở đây nhưng nghe có vẻ cũng là một giải pháp tốt.


Về cơ bản đó là thiết kế OO mà chúng ta đã có ngay bây giờ. Một thực thể, với các công cụ phái sinh (Nhân vật, Quái vật), v.v., tôi đã lãnh đạo một nhóm chúng tôi đã làm việc toàn thời gian trong gần 2 năm và với mọi người thay đổi mọi thứ theo ý muốn, nó trở thành một điều kinh khủng, khủng khiếp codebase - và bắt đầu mất một thời gian dài lúng túng để đưa các tính năng mới được vận chuyển. Ý tưởng Hệ thống thực thể dường như chính xác là những gì tôi đang tìm kiếm, vì vậy trong khi câu trả lời của bạn không hoàn toàn phù hợp, bạn nên tự đọc các liên kết ở đầu câu hỏi, xem họ có thể giúp bạn không :)
Chú ý

@Sticky Tôi phải thừa nhận rằng Hệ thống Node cộng với Thực thể được tạo thành từ các thành phần là một cách thông minh để thể hiện các hệ thống cần thiết khác với cách tiếp cận bộ điều khiển được đề xuất của tôi giống như một phiên bản ít phát triển hơn. Bạn thực sự không cần câu trả lời của tôi sau tất cả.
Hatoru Hansou

Đừng lo lắng. Cách OO có lợi thế của nó, nhưng mọi thứ trở nên xấu xí, nhanh chóng
Chú ý
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.