Làm thế nào để thực hiện đúng việc xử lý tin nhắn trong một hệ thống thực thể dựa trên thành phần?


30

Tôi đang thực hiện một biến thể hệ thống thực thể có:

  • Một lớp Thực thể ít hơn một ID liên kết các thành phần lại với nhau

  • Một nhóm các lớp thành phần không có "logic thành phần", chỉ có dữ liệu

  • Một nhóm các lớp hệ thống (còn gọi là "hệ thống con", "người quản lý"). Chúng làm tất cả các xử lý logic thực thể. Trong hầu hết các trường hợp cơ bản, các hệ thống chỉ lặp đi lặp lại một danh sách các thực thể mà chúng quan tâm và thực hiện một hành động đối với mỗi chúng

  • Một đối tượng lớp MessageChannel được chia sẻ bởi tất cả các hệ thống trò chơi. Mỗi hệ thống có thể đăng ký loại tin nhắn cụ thể để nghe và cũng có thể sử dụng kênh để truyền phát tin nhắn đến các hệ thống khác

Biến thể ban đầu của xử lý tin nhắn hệ thống là như thế này:

  1. Chạy một bản cập nhật trên mỗi hệ thống trò chơi một cách tuần tự
  2. Nếu một hệ thống làm điều gì đó với một thành phần và hành động đó có thể được các hệ thống khác quan tâm, thì hệ thống sẽ gửi một thông điệp thích hợp (ví dụ: một cuộc gọi hệ thống

    messageChannel.Broadcast(new EntityMovedMessage(entity, oldPosition, newPosition))

    Bất cứ khi nào một thực thể được di chuyển)

  3. Mỗi hệ thống đăng ký tin nhắn cụ thể được gọi là phương thức xử lý tin nhắn

  4. Nếu một hệ thống đang xử lý một sự kiện và logic xử lý sự kiện yêu cầu một thông điệp khác được phát đi, thông báo sẽ được phát ngay lập tức và một chuỗi các phương thức xử lý tin nhắn khác được gọi

Biến thể này vẫn ổn cho đến khi tôi bắt đầu tối ưu hóa hệ thống phát hiện va chạm (nó đang trở nên rất chậm khi số lượng thực thể tăng lên). Lúc đầu, nó sẽ chỉ lặp lại mỗi cặp thực thể bằng thuật toán đơn giản. Sau đó, tôi đã thêm một "chỉ mục không gian" có một lưới các ô lưu trữ các thực thể nằm trong khu vực của một ô cụ thể, do đó chỉ cho phép kiểm tra các thực thể trong các ô lân cận.

Mỗi khi một thực thể di chuyển, hệ thống va chạm sẽ kiểm tra xem thực thể đó có va chạm với thứ gì đó ở vị trí mới hay không. Nếu có, một vụ va chạm được phát hiện. Và nếu cả hai thực thể va chạm là "vật thể" (cả hai đều có thành phần RigidBody và có nghĩa là đẩy nhau ra xa để không chiếm cùng một không gian), một hệ thống tách thân cứng chuyên dụng yêu cầu hệ thống chuyển động di chuyển các thực thể đến một số vị trí cụ thể sẽ tách chúng ra. Điều này đến lượt nó làm cho hệ thống chuyển động gửi tin nhắn thông báo về các vị trí thực thể đã thay đổi. Hệ thống phát hiện va chạm có nghĩa là phản ứng vì nó cần cập nhật chỉ số không gian của nó.

Trong một số trường hợp, nó gây ra sự cố do nội dung của ô (Danh sách các đối tượng Thực thể chung trong C #) bị sửa đổi trong khi chúng bị lặp đi lặp lại, do đó gây ra một ngoại lệ bị lặp bởi trình lặp.

Vậy ... làm thế nào tôi có thể ngăn hệ thống va chạm bị gián đoạn trong khi nó kiểm tra va chạm?

Tất nhiên tôi có thể thêm một số logic "thông minh" / "khó hiểu" để đảm bảo nội dung ô được lặp lại một cách chính xác, nhưng tôi nghĩ vấn đề không nằm ở chính hệ thống va chạm (tôi cũng gặp vấn đề tương tự trong các hệ thống khác), nhưng cách tin nhắn được xử lý khi chúng đi từ hệ thống này sang hệ thống khác. Những gì tôi cần là một số cách để đảm bảo rằng một phương thức xử lý sự kiện cụ thể sẽ thực hiện công việc mà không bị gián đoạn.

Những gì tôi đã thử:

  • Hàng đợi tin nhắn đến . Mỗi khi một số hệ thống phát thông báo, tin nhắn sẽ được thêm vào hàng đợi tin nhắn của các hệ thống quan tâm đến nó. Các thông báo này được xử lý khi một bản cập nhật hệ thống được gọi là mỗi khung. Vấn đề : nếu hệ thống A thêm thông báo vào hàng B của hệ thống, nó sẽ hoạt động tốt nếu hệ thống B có nghĩa là được cập nhật muộn hơn hệ thống A (trong cùng khung trò chơi); mặt khác, nó làm cho thông báo xử lý khung trò chơi tiếp theo (không mong muốn đối với một số hệ thống)
  • Hàng đợi tin nhắn đi . Trong khi một hệ thống đang xử lý một sự kiện, bất kỳ tin nhắn nào nó phát sẽ được thêm vào hàng đợi tin nhắn đi. Các thông báo không cần đợi bản cập nhật hệ thống được xử lý: chúng được xử lý "ngay lập tức" sau khi trình xử lý tin nhắn ban đầu kết thúc. Nếu việc xử lý các tin nhắn khiến các tin nhắn khác được phát, chúng cũng được thêm vào hàng đợi gửi đi, vì vậy tất cả các tin nhắn đều được xử lý cùng một khung. Vấn đề: nếu hệ thống trọn đời thực thể (tôi đã triển khai quản lý trọn đời thực thể với một hệ thống) tạo ra một thực thể, nó sẽ thông báo cho một số hệ thống A và B về nó. Trong khi hệ thống A xử lý tin nhắn, nó gây ra một chuỗi các thông điệp cuối cùng khiến thực thể được tạo ra bị phá hủy (ví dụ, một thực thể viên đạn đã được tạo ngay khi nó va chạm với một chướng ngại vật nào đó, khiến viên đạn tự hủy). Trong khi chuỗi thông báo đang được giải quyết, hệ thống B không nhận được thông báo tạo thực thể. Vì vậy, nếu hệ thống B cũng quan tâm đến thông báo hủy thực thể, thì nó sẽ nhận được nó và chỉ sau khi "chuỗi" giải quyết xong, nó mới nhận được thông báo tạo thực thể ban đầu. Điều này khiến thông báo hủy bị bỏ qua, thông báo tạo được "chấp nhận",

EDIT - TRẢ LỜI CÂU HỎI, NHẬN XÉT:

  • Ai sửa đổi nội dung của tế bào trong khi hệ thống va chạm lặp lại trên chúng?

Trong khi hệ thống va chạm đang thực hiện kiểm tra va chạm trên một số thực thể và đó là hàng xóm, một vụ va chạm có thể bị phát hiện và hệ thống thực thể sẽ gửi một thông điệp sẽ được phản ứng ngay lập tức bởi các hệ thống khác. Phản ứng với tin nhắn có thể khiến các tin nhắn khác được tạo và cũng được xử lý ngay lập tức. Vì vậy, một số hệ thống khác có thể tạo ra một thông báo rằng hệ thống va chạm sau đó sẽ cần xử lý ngay lập tức (ví dụ: một thực thể di chuyển để hệ thống va chạm cần cập nhật chỉ số không gian của nó), mặc dù các kiểm tra va chạm trước đó vẫn chưa kết thúc.

  • Bạn không thể làm việc với hàng đợi tin nhắn gửi đi toàn cầu?

Tôi đã thử một hàng đợi toàn cầu gần đây. Nó gây ra vấn đề mới. Vấn đề: Tôi di chuyển một thực thể xe tăng vào một thực thể tường (bể được điều khiển bằng bàn phím). Sau đó, tôi quyết định thay đổi hướng của xe tăng. Để tách bể và tường mỗi khung, CollidingRigidBodySeparationSystem di chuyển bể ra khỏi tường bằng số lượng nhỏ nhất có thể. Hướng phân tách phải ngược với một trong các hướng di chuyển của xe tăng (khi bản vẽ trò chơi bắt đầu, chiếc xe tăng sẽ trông như thể nó không bao giờ di chuyển vào tường). Nhưng hướng trở nên ngược lại với hướng MỚI, do đó di chuyển xe tăng sang một phía khác của bức tường so với ban đầu. Tại sao sự cố xảy ra: Đây là cách xử lý thư bây giờ (mã đơn giản):

public void Update(int deltaTime)
{   
    m_messageQueue.Enqueue(new TimePassedMessage(deltaTime));
    while (m_messageQueue.Count > 0)
    {
        Message message = m_messageQueue.Dequeue();
        this.Broadcast(message);
    }
}

private void Broadcast(Message message)
{       
    if (m_messageListenersByMessageType.ContainsKey(message.GetType()))
    {
        // NOTE: all IMessageListener objects here are systems.
        List<IMessageListener> messageListeners = m_messageListenersByMessageType[message.GetType()];
        foreach (IMessageListener listener in messageListeners)
        {
            listener.ReceiveMessage(message);
        }
    }
}

Mã chảy như thế này (giả sử đó không phải là khung trò chơi đầu tiên):

  1. Hệ thống bắt đầu xử lý TimePassedMessage
  2. InputHandingSystem chuyển đổi các lần nhấn phím thành hành động thực thể (trong trường hợp này, một mũi tên bên trái biến thành hành động MoveWest). Hành động thực thể được lưu trữ trong thành phần ActionExecutor
  3. ActionExecutSystem , phản ứng với hành động thực thể, thêm MovementDirectionChangeRequestedMessage vào cuối hàng đợi tin nhắn
  4. MovementSystem di chuyển vị trí thực thể dựa trên dữ liệu thành phần Vận tốc và thêm thông báo PositionChangedMessage vào cuối hàng đợi. Chuyển động được thực hiện bằng cách sử dụng hướng / vận tốc của khung trước đó (giả sử là phía bắc)
  5. Hệ thống ngừng xử lý TimePassedMessage
  6. Các hệ thống bắt đầu xử lý MovementDirectionChangeRequestedMessage
  7. MovementSystem thay đổi vận tốc / hướng di chuyển của thực thể theo yêu cầu
  8. Các hệ thống ngừng xử lý MovementDirectionChangeRequestedMessage
  9. Hệ thống bắt đầu xử lý PositionChangedMessage
  10. CollisionDetectionSystem phát hiện ra rằng vì một thực thể di chuyển, nó đã chạy vào một thực thể khác (xe tăng đi vào bên trong một bức tường). Nó thêm CollisionOccuredMessage vào hàng đợi
  11. Hệ thống ngừng xử lý PositionChangedMessage
  12. Hệ thống bắt đầu xử lý CollisionOccuredMessage
  13. CollidingRigidBodySpayationSystem phản ứng với sự va chạm bằng cách tách bể và tường. Vì tường là tĩnh, chỉ có bể được di chuyển. Hướng di chuyển của xe tăng được sử dụng như một chỉ báo về nơi xe tăng đến từ đâu. Nó được bù theo hướng ngược lại

LGI: Khi xe tăng di chuyển khung này, nó di chuyển bằng hướng di chuyển từ khung trước đó, nhưng khi nó được tách ra, hướng di chuyển từ khung NÀY đã được sử dụng, mặc dù nó đã khác. Đó không phải là cách nó nên hoạt động!

Để ngăn chặn lỗi này, hướng di chuyển cũ cần được lưu ở đâu đó. Tôi có thể thêm nó vào một số thành phần chỉ để sửa lỗi cụ thể này, nhưng không phải trường hợp này chỉ ra một số cách xử lý thông điệp sai về cơ bản? Tại sao hệ thống phân tách nên quan tâm hướng di chuyển mà nó sử dụng? Làm thế nào tôi có thể giải quyết vấn đề này một cách thanh lịch?

  • Bạn có thể muốn đọc gamadu.com/artemis để xem những gì họ đã làm với Aspects, bên nào giải quyết một số vấn đề bạn đang gặp phải.

Thật ra, tôi đã quen với Artemis khá lâu rồi. Điều tra nó là mã nguồn, đọc diễn đàn, v.v. Nhưng tôi đã thấy "Các khía cạnh" chỉ được đề cập ở một vài nơi và, theo như tôi hiểu, về cơ bản chúng có nghĩa là "Hệ thống". Nhưng tôi không thể thấy cách phía Artemis giải quyết một số vấn đề của tôi. Nó thậm chí không sử dụng tin nhắn.

  • Xem thêm: "Giao tiếp thực thể: Hàng đợi tin nhắn vs Xuất bản / Đăng ký vs Tín hiệu / Slots"

Tôi đã đọc tất cả các câu hỏi gamedev.stackexchange liên quan đến các hệ thống thực thể. Điều này dường như không thảo luận về những vấn đề tôi đang gặp phải. Tui bỏ lỡ điều gì vậy?

  • Xử lý hai trường hợp khác nhau, cập nhật lưới không cần dựa vào các thông báo chuyển động vì đây là một phần của hệ thống va chạm

Tôi không chắc ý của bạn là gì. Các triển khai CollisionDetectionSystem cũ hơn sẽ chỉ kiểm tra các xung đột trên một bản cập nhật (khi TimePassedMessage được xử lý), nhưng tôi phải giảm thiểu kiểm tra nhiều nhất có thể do hiệu suất. Vì vậy, tôi chuyển sang kiểm tra va chạm khi một thực thể di chuyển (hầu hết các thực thể trong trò chơi của tôi là tĩnh).


Có điều gì đó không rõ ràng với tôi. Ai sửa đổi nội dung của ô trong khi hệ thống va chạm lặp lại trên chúng?
Paul Manta

Bạn không thể làm việc với hàng đợi tin nhắn gửi đi toàn cầu? Vì vậy, tất cả các tin nhắn trong đó được gửi mỗi lần sau khi một hệ thống được thực hiện, điều này bao gồm cả việc tự hủy hệ thống.
Roy T.

Nếu bạn muốn giữ thiết kế phức tạp này thì bạn phải tuân theo @RoyT. Lời khuyên, đó là cách duy nhất (không có nhắn tin dựa trên thời gian phức tạp) để xử lý vấn đề tuần tự của bạn. Bạn có thể muốn đọc gamadu.com/artemis để xem những gì họ đã làm với Aspects, bên nào giải quyết một số vấn đề bạn đang gặp phải.
Patrick Hughes


2
Bạn có thể muốn tìm hiểu cách Axum đã làm điều đó bằng cách tải xuống CTP và biên dịch một số mã - và sau đó đảo ngược kết quả thành C # bằng ILSpy. Truyền tin nhắn là một tính năng quan trọng của ngôn ngữ mô hình diễn viên và tôi chắc chắn Microsoft biết họ đang làm gì - vì vậy bạn có thể thấy họ đã thực hiện 'tốt nhất'.
Jonathan Dickinson

Câu trả lời:


12

Bạn có thể đã nghe nói về mô hình chống đối tượng God / Blob. Vâng, vấn đề của bạn là một vòng lặp God / Blob. Nháy mắt với hệ thống chuyển tin nhắn của bạn sẽ cung cấp giải pháp Band-Aid tốt nhất và tệ nhất là hoàn toàn lãng phí thời gian. Trong thực tế, vấn đề của bạn không liên quan gì đến phát triển trò chơi cả. Tôi đã bắt gặp mình đang cố gắng sửa đổi một bộ sưu tập trong khi lặp đi lặp lại nhiều lần và giải pháp luôn giống nhau: chia nhỏ, chia nhỏ, chia nhỏ.

Theo tôi hiểu từ ngữ của câu hỏi của bạn, phương pháp cập nhật hệ thống va chạm của bạn hiện tại trông giống như sau.

for each possible collision
    check for collision
    handle collision
    modify collision world to reflect change // exception happens here

Được viết đơn giản như thế này, bạn có thể thấy rằng vòng lặp của bạn có ba trách nhiệm, khi nó chỉ nên có một trách nhiệm. Để giải quyết vấn đề của bạn, hãy chia vòng lặp hiện tại của bạn thành ba vòng riêng biệt đại diện cho ba lần chuyển thuật toán khác nhau .

for each possible collision
    check for collision, record it if a collision occurs

for each found collision
    handle collision, record the collision response (delete object, ignore, etc.)

for each collision response
    modify collision world according to response

Bằng cách chia vòng lặp ban đầu của bạn thành ba nhóm con, bạn không còn cố gắng sửa đổi bộ sưu tập mà bạn hiện đang lặp lại. Cũng lưu ý rằng bạn không thực hiện nhiều công việc hơn trong vòng lặp ban đầu của mình và trên thực tế bạn có thể đạt được một số chiến thắng bộ đệm bằng cách thực hiện các hoạt động tương tự nhiều lần liên tục.

Ngoài ra còn có một lợi ích nữa, đó là bây giờ bạn có thể đưa tính song song vào mã của mình. Cách tiếp cận vòng lặp kết hợp của bạn vốn là nối tiếp (về cơ bản là những gì ngoại lệ sửa đổi đồng thời đang nói với bạn!), Bởi vì mỗi lần lặp lặp có khả năng cả đọc và ghi vào thế giới va chạm của bạn. Ba phân nhóm tôi trình bày ở trên, tuy nhiên, tất cả đều đọc hoặc viết, nhưng không phải cả hai. Ít nhất là lần đầu tiên vượt qua, kiểm tra tất cả các va chạm có thể xảy ra, đã trở nên song song một cách đáng xấu hổ, và tùy thuộc vào cách bạn viết mã của mình, lần thứ hai và thứ ba có thể cũng vậy.


Tôi hoàn toàn đồng ý với điều này. Tôi đang sử dụng cách tiếp cận tương tự này trong trò chơi của mình và tôi tin rằng điều này sẽ mang lại kết quả lâu dài. Đây là cách hệ thống va chạm (hoặc người quản lý) nên hoạt động (tôi thực sự tin rằng không thể có một hệ thống nhắn tin nào cả).
Emiliano

11

Làm thế nào để thực hiện đúng việc xử lý tin nhắn trong một hệ thống thực thể dựa trên thành phần?

Tôi muốn nói rằng bạn muốn có hai loại tin nhắn: Đồng bộ và Không đồng bộ. Tin nhắn đồng bộ được xử lý ngay lập tức trong khi không đồng bộ được xử lý không trong cùng một khung ngăn xếp (nhưng có thể được xử lý trong cùng một khung trò chơi). Quyết định thường được đưa ra trên cơ sở "mỗi lớp tin nhắn", ví dụ: "tất cả các tin nhắn EnemyDied là không đồng bộ".

Một số sự kiện được xử lý dễ dàng hơn nhiều với một trong những cách này. Ví dụ, theo kinh nghiệm của tôi, ObjectGetsDelattedNow - sự kiện ít hấp dẫn hơn và các cuộc gọi lại khó thực hiện hơn nhiều so với ObjectWillBeDelattedAtEndOfFrame. Sau đó, một lần nữa, bất kỳ trình xử lý thông báo giống như "phủ quyết" nào (mã có thể hủy hoặc sửa đổi một số hành động nhất định trong khi chúng được thực thi, như hiệu ứng Shield sửa đổi DamageEvent ) sẽ không dễ dàng trong các môi trường không đồng bộ nhưng là một miếng bánh trong cuộc gọi đồng bộ.

Asyncronous có thể hiệu quả hơn trong một số trường hợp (ví dụ: bạn có thể bỏ qua một số trình xử lý sự kiện khi đối tượng bị xóa sau đó). Đôi khi, đồng bộ hiệu quả hơn, đặc biệt là khi tính toán tham số cho một sự kiện tốn kém và bạn muốn truyền các hàm gọi lại để lấy các tham số nhất định thay vì các giá trị đã được tính toán (trong trường hợp không ai quan tâm đến tham số cụ thể này).

Bạn đã đề cập đến một vấn đề chung khác với các hệ thống tin nhắn chỉ đồng bộ: Theo kinh nghiệm của tôi với các hệ thống tin nhắn đồng bộ, một trong những trường hợp lỗi và đau buồn nói chung là thay đổi danh sách trong khi lặp qua các danh sách này.

Hãy suy nghĩ về nó: Đó là bản chất của sự đồng bộ (xử lý ngay lập tức tất cả hậu quả của một số hành động) và hệ thống tin nhắn (tách người nhận từ người gửi để người gửi không biết ai đang phản ứng với hành động) mà bạn sẽ không thể dễ dàng phát hiện ra các vòng như vậy. Điều tôi đang nói là: Hãy chuẩn bị để xử lý kiểu lặp tự sửa đổi này rất nhiều. Đó là loại "theo thiết kế". ;-)

Làm thế nào tôi có thể ngăn hệ thống va chạm bị gián đoạn trong khi nó kiểm tra va chạm?

Đối với vấn đề cụ thể của bạn với phát hiện va chạm, có thể đủ tốt để làm cho các sự kiện va chạm không đồng bộ, do đó chúng được xếp hàng cho đến khi trình quản lý va chạm kết thúc và được thực hiện như một đợt sau đó (hoặc tại một số điểm sau trong khung). Đây là giải pháp "hàng đợi đến" của bạn.

Vấn đề: nếu hệ thống A thêm thông báo vào hàng B của hệ thống, nó sẽ hoạt động tốt nếu hệ thống B có nghĩa là được cập nhật muộn hơn hệ thống A (trong cùng khung trò chơi); mặt khác, nó làm cho thông báo xử lý khung trò chơi tiếp theo (không mong muốn đối với một số hệ thống)

Dễ dàng:

while (! queue.empty ()) {queue.pop (). handle (); }

Chỉ cần chạy hàng đợi nhiều lần cho đến khi không còn tin nhắn. (Nếu bạn hét lên "vòng lặp vô tận" bây giờ, hãy nhớ rằng rất có thể bạn sẽ gặp vấn đề này là "spam tin nhắn" nếu nó bị trì hoãn sang khung tiếp theo. Bạn có thể khẳng định () cho một số lần lặp lại lành mạnh để phát hiện các vòng lặp vô tận, Nếu bạn cảm thấy thích nó ;))


Lưu ý rằng tôi không nói chính xác "khi nào" tin nhắn không đồng bộ được xử lý. Theo tôi, nó hoàn toàn ổn khi cho phép mô-đun phát hiện va chạm tuôn ra các thông điệp của nó sau khi kết thúc. Bạn cũng có thể coi đây là "tin nhắn đồng bộ, bị trì hoãn cho đến hết vòng lặp" hoặc một cách tiện lợi nào đó "chỉ thực hiện phép lặp theo cách có thể sửa đổi trong khi lặp lại"
Imi 17/212

5

Nếu bạn thực sự đang cố gắng sử dụng bản chất thiết kế hướng dữ liệu của ECS thì bạn có thể muốn nghĩ về cách thức DOD nhất để thực hiện việc này.

Hãy xem blog BitSquid , cụ thể là phần về các sự kiện. Một hệ thống phù hợp với ECS được trình bày. Bộ đệm tất cả các sự kiện vào một hàng đợi loại tin nhắn sạch đẹp, giống như các hệ thống trong ECS ​​là mỗi thành phần. Các hệ thống được cập nhật sau đó có thể lặp lại một cách hiệu quả qua hàng đợi cho một loại thông báo cụ thể để xử lý chúng. Hoặc chỉ cần bỏ qua chúng. Cái nào cũng được.

Ví dụ, CollisionSystem sẽ tạo ra một bộ đệm chứa đầy các sự kiện va chạm. Bất kỳ hệ thống nào khác chạy sau khi va chạm đều có thể lặp qua danh sách và xử lý những thứ cần thiết.

Nó giữ bản chất song song hướng dữ liệu của thiết kế ECS mà không cần tất cả sự phức tạp của việc đăng ký tin nhắn hoặc tương tự. Chỉ các hệ thống thực sự quan tâm đến một loại sự kiện cụ thể lặp qua hàng đợi cho loại đó và thực hiện một bước lặp đơn thông qua hàng đợi tin nhắn là hiệu quả như bạn có thể nhận được.

Nếu bạn giữ các thành phần được sắp xếp một cách nhất quán trong mỗi hệ thống (ví dụ: sắp xếp tất cả các thành phần theo id thực thể hoặc đại loại như thế) thì bạn thậm chí sẽ nhận được lợi ích tốt đẹp mà các thông điệp sẽ được tạo theo thứ tự hiệu quả nhất để lặp qua chúng và tìm kiếm các thành phần tương ứng trong Hệ thống xử lý. Đó là, nếu bạn có các thực thể 1, 2, & 3 thì các tin nhắn được tạo theo thứ tự đó và tra cứu thành phần được thực hiện trong khi xử lý tin nhắn sẽ theo thứ tự địa chỉ tăng nghiêm ngặt (nhanh nhất).


1
+1, nhưng tôi không thể tin rằng phương pháp này không có nhược điểm. Điều này không buộc chúng ta phải phụ thuộc lẫn nhau giữa các hệ thống sao? Hoặc có thể những phụ thuộc lẫn nhau này có nghĩa là được mã hóa cứng, bằng cách này hay cách khác?
Patryk Czachurski

2
@Daedalus: nếu logic trò chơi cần cập nhật vật lý để thực hiện logic chính xác, làm thế nào bạn sẽ không có sự phụ thuộc đó? Ngay cả với một mô hình pubsub, bạn phải đăng ký rõ ràng loại tin nhắn tương tự và chỉ được tạo bởi một số hệ thống khác. Tránh phụ thuộc là khó, và chủ yếu chỉ là tìm ra các lớp bên phải. Đồ họa và vật lý là độc lập, chẳng hạn, nhưng sẽ có một lớp keo ở cấp độ cao hơn để đảm bảo các cập nhật mô phỏng vật lý được nội suy được phản ánh trong đồ họa, v.v.
Sean Middleditch

Đây phải là câu trả lời được chấp nhận. Một cách đơn giản để thực hiện điều này là chỉ cần tạo một loại thành phần mới, ví dụ CollisionResolvable sẽ được xử lý bởi mọi hệ thống quan tâm đến việc thực hiện sau khi xảy ra va chạm. Điều này sẽ phù hợp với đề xuất của Drake, tuy nhiên có một hệ thống cho mọi vòng lặp phân khu.
dùng8363
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.