Làm thế nào để nối máy trạng thái hữu hạn vào kiến ​​trúc dựa trên thành phần? [đóng cửa]


23

Các máy trạng thái dường như gây ra sự phụ thuộc có hại trong các kiến ​​trúc dựa trên thành phần.

Cụ thể, giao tiếp được xử lý như thế nào giữa một máy trạng thái và các thành phần thực hiện hành vi liên quan đến trạng thái?

Tôi đang ở đâu:

  • Tôi chưa quen với kiến ​​trúc dựa trên thành phần.
  • Tôi đang làm một trò chơi chiến đấu, mặc dù tôi không nghĩ điều đó quan trọng. Tôi hình dung máy trạng thái của tôi đang được sử dụng để chuyển đổi các trạng thái như "cúi mình", "lao", "chặn", v.v.
  • Tôi đã thấy kỹ thuật quản lý nhà nước này là hệ thống tự nhiên nhất cho kiến ​​trúc dựa trên thành phần, nhưng nó mâu thuẫn với các kỹ thuật tôi đã đọc về: Hệ thống thành phần đối tượng trò chơi động cho các nhân vật hành vi có thể thay đổi Nó gợi ý rằng tất cả các thành phần kích hoạt / hủy kích hoạt chính họ bằng cách liên tục kiểm tra một điều kiện để kích hoạt.
  • Tôi nghĩ rằng các hành động như "chạy" hoặc "đi bộ" có ý nghĩa như các trạng thái, không đồng ý với phản hồi được chấp nhận ở đây: /gamedev//a/7934
  • Tôi đã thấy điều này hữu ích, nhưng mơ hồ: Làm thế nào để thực hiện hành vi trong kiến ​​trúc trò chơi dựa trên thành phần? Nó gợi ý có một thành phần riêng biệt không chứa gì ngoài một máy trạng thái. Nhưng, điều này đòi hỏi một số loại khớp nối giữa thành phần máy trạng thái và gần như tất cả các thành phần khác. Tôi không hiểu cách xử lý khớp nối này. Đây là một số dự đoán:

    A. Các thành phần phụ thuộc vào máy trạng thái:
    Các thành phần nhận được tham chiếu đến thành phần của máy trạng thái getState(), trả về hằng số liệt kê. Các thành phần tự cập nhật thường xuyên và kiểm tra điều này khi cần thiết.

    B. Máy
    trạng thái phụ thuộc vào các thành phần: Thành phần máy trạng thái nhận các tham chiếu đến tất cả các thành phần mà nó giám sát. Nó truy vấn các getState()phương thức của họ để xem họ đang ở đâu.

    C. Một số trừu tượng giữa chúng
    Sử dụng một trung tâm sự kiện? Mẫu lệnh?

    D. Các đối tượng trạng thái riêng biệt tham chiếu thành phần
    Mẫu trạng thái được sử dụng. Các đối tượng trạng thái riêng biệt được tạo, kích hoạt / hủy kích hoạt một tập hợp các thành phần. Máy trạng thái chuyển đổi giữa các đối tượng nhà nước.

  • Tôi đang xem các thành phần như triển khai các khía cạnh . Họ làm mọi thứ cần thiết trong nội bộ để biến khía cạnh đó thành hiện thực. Có vẻ như các thành phần nên tự hoạt động, mà không cần dựa vào các thành phần khác. Tôi biết một số phụ thuộc là cần thiết, nhưng các máy trạng thái dường như muốn kiểm soát tất cả các thành phần của tôi.

Câu trả lời:


7

Tổng quan khá nhẹ, nhưng hãy xem các slide này từ một bài thuyết trình tôi đã làm cho New Game Conf năm ngoái:

https://docs.google.com/presentation/d/110MxOqut_y7KOW1pNwIdcccisIA3ooJwVR-xm-ecuc4/view

(xem hình ảnh thích hợp bên dưới)

Ý chính của kỹ thuật là kết hợp mô hình danh sách hành động (được giải thích - hơi kém - trong các slide) với các máy trạng thái hành vi hoạt động dựa trên thực thể trò chơi dựa trên thành phần.

Về bản chất, nó giống như việc tạo ra một hệ thống sáng tác đặc biệt chỉ dành cho hành vi AI, hướng đến các loại tích hợp liên hành vi mà bạn cần cho các hệ thống AI đơn giản hơn.

Phần yêu thích của tôi trong trò chơi cụ thể đó là cách chúng tôi có thể tạo ra các loại kẻ thù hoàn toàn mới bằng cách chỉ cần chọn từ danh sách các hành vi được viết sẵn, đưa chúng vào danh sách hành động cho đối tượng trò chơi (nằm trong BrainComponent) theo thứ tự mong muốn ưu tiên, và mọi thứ chỉ hoạt động. Với một danh sách hành động cho phép thực hiện các hành động Chặn / Không khóa, điều này có thể thực hiện một số điều thực sự thú vị mặc dù tất cả đều đơn giản để thực hiện.

Ngay cả những hành vi như "làm choáng" khi thực sự chỉ là StunBehaviorAction được đẩy lên đầu danh sách xếp hạng hành động; nếu hành vi gây choáng được kích hoạt (sau khi quan sát thấy EarsComponent của đối tượng trò chơi nghe thấy một cuộc tấn công sóng xung kích tuyệt đẹp) thì nó sẽ đặt trạng thái bên trong thành Stunned, nói với AnimationComponent chơi hoạt hình gây choáng và đặt trạng thái hành động của nó thành Chặn và hẹn giờ thời gian chờ choáng được lấy từ EnemyParameterComponent của đối tượng trò chơi. Vì nó là Chặn và ở đầu danh sách hành động, không một hành vi nào khác trong danh sách hành động sẽ nhận được phương thức cập nhật của chúng, vì vậy về cơ bản chúng sẽ bị tắt. Khi hết thời gian, StunBehaviorAction đặt trạng thái của nó trở lại Idle và trạng thái hành động của nó thành NonBlocking.

Các hành vi khác mà chúng tôi thực hiện hầu hết đều được thực hiện với một máy trạng thái nội bộ duy nhất. Trên thực tế, hai chiếc duy nhất không có máy trạng thái là PatrolPathBehaviorAction (nó sẽ đẩy một loạt PathAction vào danh sách hành động nếu nó không hoạt động, lần lượt đẩy MoveAction) và GuardHomeBehaviorAction (luôn ở cuối trang danh sách hành động và sẽ luôn đẩy PathAction trở lại vị trí nhà của kẻ thù). Mọi hành vi khác là một bộ máy nhà nước.

Trượt 10 Trượt 25 Trượt 26


Sự khác biệt cơ bản giữa "Hành vi" và "Hành động" là gì?
Pup

1
@Pup: Từ góc độ mã, khi tôi xây dựng nó, Hành vi là một Hành động. Từ quan điểm khái niệm, Hành động thường là nhất thời - chúng chỉ tồn tại cho đến khi "hoàn thành" - trong khi Hành vi là mãi mãi và không bao giờ bị xóa khỏi danh sách. Tôi đã thấy một nhóm khác xây dựng một hệ thống tương tự nhưng với hai danh sách, một cho Hành động và một cho Hành vi, hoạt động đủ tốt. Tuy nhiên, tôi thích có khả năng cho một Hành động chặn một số hành vi nhất định, bằng cách sử dụng bitmasks và nhóm (làn, tôi tin rằng tôi đã gọi chúng trong các slide). Xin lỗi rằng đồ họa của slide giữa rất tệ. :)
Sean Middleditch

3

Tại một công ty trước đây tôi làm việc cho chúng tôi có một hệ thống dựa trên thành phần với AI dựa trên nhà nước. Chúng tôi đã có một thành phần AI kiểm soát tất cả hành vi cho đối tượng / đơn vị đó. Khi AI hoạt động, như đi lang thang, tấn công, v.v., nó sẽ nhận được cập nhật từng khung hình để thực hiện bất kỳ logic nào cần thiết. Khi AI không hoạt động hoặc không di chuyển, thành phần đã bị hủy kích hoạt và không được cập nhật từng khung. Thành phần này, dù đã bị vô hiệu hóa, vẫn có thể nhận được các tin nhắn dựa trên sự kiện, do đó, nó sẽ nhận được một tin nhắn cho một thứ giống như người chơi đi vào bán kính aggro của nó và có thể phản hồi lại bằng cách kích hoạt lại thành phần AI để nó có thể cập nhật dựa trên khung.

Thành phần AI có các thành phần phụ, nó có thể tạo và phá hủy nhanh chóng, dựa trên loại hành động mà nó đang thực hiện. Ví dụ, nếu nó đi lang thang, nó có thể tạo ra một thành phần phụ lang thang và cập nhật từng khung hình trong khi đi lang thang, và sau đó nếu aggro'd trong khi lang thang, nó sẽ đóng thành phần phụ đó và mở một thành phần phụ tấn công. Thành phần AI phải độc lập với tất cả các thành phần khác trên một đối tượng. Ví dụ: chúng tôi có một thành phần đầu vào, đơn giản là sẽ truy vấn các giá trị chuyển động trên một đơn vị. Truy vấn mà nó đưa ra là thứ mà cả đối tượng người và AI sẽ phản hồi. Điều này cho phép thành phần AI chỉ đơn giản là tự đặt giá trị chuyển động trong những thứ như đi lang thang, mà thành phần đầu vào có thể nhận, giống như một thành phần có thể điều khiển được của con người sẽ đặt các giá trị mà thành phần đầu vào có thể nhận được.


Vì vậy, các thành phần phụ AI đang thực sự làm việc? Có phải chúng tồn tại dưới dạng các thành phần thực thể, ở cùng cấp độ với thành phần AI?
Pup

Các thành phần phụ trong động cơ của chúng tôi là một phần của lớp thành phần cơ sở. Vì vậy, bất kỳ Component, có nguồn gốc từ BaseComponent, có thể có bất kỳ số SubComponents trên đó. Các Update()phương pháp trong BaseComponentsẽ kiểm tra danh sách các thành phần phụ, và gọi Update()trên những. Subcomponentslà hoàn toàn tùy chọn vì vậy BaseComponentcó thể không có bất kỳ. Ngoài ra, bất kỳ thư nào đi đến một thành phần cũng được chuyển đến các thành phần con.
Nic Foster

1

Có một chút không rõ ý của bạn về các thành phần vì các điều khoản của bạn rất mơ hồ không có ví dụ cụ thể. Thông thường các thực thể trò chơi được xây dựng bằng cách sử dụng thành phần chứ không phải kế thừa. Do đó, bạn có thể biến chúng thành thứ gì đó có thể gây sát thương bằng cách thêm một thành phần sức khỏe vào thực thể hoặc bạn có thể biến chúng thành hoạt hình bằng cách thêm một thành phần animate. Người ta cũng có thể đặt AI vào một thành phần như vậy. Sẽ có logic đưa ra quyết định trong thành phần AI của bạn và nếu bạn lo ngại về việc ghép mã đó với nhiều mã khác trong hệ thống, bạn có thể thu thập thông tin vào bảng đen mà logic AI chỉ được phép truy cập. Ngoài ra còn có vấn đề phụ thuộc vào đầu ra của hệ thống AI. Về cơ bản AI của bạn đang kiểm soát một thực thể và điều khiển đó cần một giao diện. Một khái niệm hữu ích là bộ điều khiển hoặc gamepad. AI của bạn có thể điền vào một cấu trúc tương tự mà gamepad của người chơi sẽ điền vào (mặc dù nó có thể có thêm một số "nút" cho các khả năng cụ thể). Bây giờ cấu trúc này sau đó có thể được chuyển đến thành phần animate của bạn để giải thích nó và chọn các hình ảnh động phù hợp để chơi. Các thành phần phụ AI khác nhau thậm chí có thể được ghi vào các trường khác nhau của cấu trúc hoặc vào cùng các trường có mức độ ưu tiên khác nhau. Nhắm và đi bộ chẳng hạn. Các thành phần phụ AI khác nhau thậm chí có thể được ghi vào các trường khác nhau của cấu trúc hoặc vào cùng các trường có mức độ ưu tiên khác nhau. Nhắm và đi bộ chẳng hạn. Các thành phần phụ AI khác nhau thậm chí có thể được ghi vào các trường khác nhau của cấu trúc hoặc vào cùng các trường có mức độ ưu tiên khác nhau. Nhắm và đi bộ chẳng hạn.

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.