Làm thế nào để thực hiện hành vi trong một kiến ​​trúc trò chơi dựa trên thành phần?


21

Tôi đang bắt đầu triển khai AI của người chơi và kẻ thù trong một trò chơi, nhưng tôi bối rối về cách thực hiện tốt nhất điều này trong kiến ​​trúc trò chơi dựa trên thành phần.

Nói rằng tôi có một nhân vật người chơi sau có thể đứng yên, chạy và vung kiếm. Người chơi có thể chuyển sang trạng thái kiếm vung từ cả trạng thái đứng yên và chạy, nhưng sau đó phải hoàn thành cú swing trước khi người chơi có thể tiếp tục đứng hoặc chạy xung quanh. Trong quá trình swing, người chơi không thể đi bộ xung quanh.

Như tôi thấy, tôi có hai cách tiếp cận thực hiện:

  • Tạo một thành phần AI duy nhất chứa tất cả logic người chơi (được tách rời khỏi thành phần thực tế hoặc được nhúng dưới dạng PlayerAIComponent). Tôi có thể dễ dàng thực thi các giới hạn trạng thái mà không cần tạo khớp nối giữa các thành phần riêng lẻ tạo thành thực thể người chơi. Tuy nhiên, thành phần AI không thể bị phá vỡ. Ví dụ, nếu tôi có một kẻ thù chỉ có thể đứng và đi lại hoặc chỉ đi xung quanh và thỉnh thoảng vung kiếm, tôi phải tạo ra các thành phần AI mới.
  • Phá vỡ hành vi trong các thành phần, mỗi thành phần xác định một trạng thái cụ thể. Sau đó tôi nhận được một StandComponent, WalkComponent và SwingComponent. Để thực thi các quy tắc chuyển đổi, tôi phải ghép từng thành phần. SwingComponent phải vô hiệu hóa StandComponent và WalkComponent trong suốt thời gian của swing. Khi tôi có một kẻ thù chỉ đứng xung quanh, thỉnh thoảng vung kiếm, tôi phải đảm bảo rằng SwingComponent chỉ vô hiệu hóa WalkComponent nếu nó có mặt. Mặc dù điều này cho phép các thành phần kết hợp và kết hợp tốt hơn, nhưng nó có thể dẫn đến một cơn ác mộng về khả năng bảo trì vì mỗi lần thêm một phụ thuộc, các thành phần hiện có phải được cập nhật để chơi độc đáo với các yêu cầu mới mà phụ thuộc vào nhân vật.

Tình huống lý tưởng là một nhà thiết kế có thể xây dựng kẻ thù / người chơi mới bằng cách kéo các thành phần vào một thùng chứa, mà không phải chạm vào một dòng mã động cơ hoặc mã script. Mặc dù tôi không chắc chắn có thể tránh được mã hóa tập lệnh, nhưng tôi muốn giữ nó đơn giản nhất có thể.

Tóm tắt tất cả: Tôi có nên gộp tất cả logic AI vào một thành phần hoặc chia từng trạng thái logic thành các thành phần riêng biệt để tạo các biến thể thực thể dễ dàng hơn không?

chỉnh sửa : Tôi nghi ngờ có một số nhầm lẫn về những gì tôi có ý nghĩa với tình huống thứ nhất và thứ hai. Tôi đã cố gắng giải thích nó trong sơ đồ dưới đây.

Sơ đồ thành phần

Lưu ý mối quan hệ giữa các quốc gia riêng lẻ và thực thể. Trong tình huống đầu tiên, một thành phần AI được xây dựng trước khi đưa vào thực thể. Một nhà thiết kế chỉ có thể chọn từ một bộ AIComponents riêng biệt được lập trình viên cung cấp. Tình huống thứ hai có các trạng thái khác nhau ở cùng cấp độ với các thành phần khác. Một nhà thiết kế giờ đây có thể tạo ra một thực thể với AI độc đáo mà không cần sự can thiệp của lập trình viên.

Câu hỏi đặt ra là đây có phải là hai lựa chọn duy nhất để cấu trúc AI trong một thực thể dựa trên thành phần và, nếu vậy, điều gì sẽ mang lại sự linh hoạt tối đa?


Tôi nghĩ rằng một câu trả lời tốt sẽ phụ thuộc vào nơi bạn muốn thực thi tính độc quyền của các hành động. Nếu bạn muốn nó nằm trong chính các đối tượng thì thiết kế sẽ khác nhiều so với nói, thực thi nó thông qua giao diện kéo và thả (Trạng thái này đã có hành động di chuyển để nó không thể có khác, thùng chứa chuyển đổi trạng thái này đã chứa một trạng thái kết thúc dựa trên thời gian, vv hoặc bất cứ điều gì).
James

2 không phải là một lựa chọn khả thi.
Coyote

Câu trả lời:


6

Nếu bạn có ý định có nhiều kẻ thù hoặc người chơi có thể mà bạn không thể tưởng tượng ngay bây giờ, thì bạn chắc chắn nên phá vỡ nó. Những gì bạn đang mô tả trong điểm thứ hai của bạn về cơ bản là mẫu trạng thái .

Tôi nghĩ rằng tôi đồng ý với Gregory rằng bạn không nên có các thành phần trạng thái đứng và đi riêng biệt. Nó chỉ là một thành phần chuyển động với tốc độ 0. Mặt khác, nếu bạn có các vật thể không thể di chuyển, bạn phải tách nó ra hoặc chỉ đặt một số loại hạn chế boolean trong trạng thái chuyển động ngăn không có vận tốc khác không .

Đối với người chơi tôi không nghĩ nó cần phải tách biệt hoàn toàn. Nó vẫn có thể sử dụng tất cả các thành phần khác, với việc bổ sung một thành phần đầu vào. Thành phần này điều khiển quá trình chuyển đổi giữa các trạng thái, trong khi ở kẻ thù, nó được điều khiển bởi AI mặc định hoặc nếu bạn muốn, các lớp con AI khác nhau mà nhà thiết kế kẻ thù của bạn có thể chọn.

chỉnh sửa: thực sự, đối với kẻ thù đứng yên của bạn, thay vì hạn chế thành phần chuyển động, chỉ cần cung cấp cho chúng thành phần AI cố định không bao giờ chọn di chuyển chúng.


Không phải một mô hình nhà nước ngụ ý tình huống đầu tiên? Điều này dẫn đến một AIComponent thực hiện một máy trạng thái chứa các đối tượng trạng thái khác nhau. Điều tôi muốn nói với tùy chọn thứ hai là WalkComponent và SwingComponent cùng loại với, như, RenderComponent và ChemistryComponent.
ma

@ghostonline Theo như ý tưởng, sắp xếp. Trong thực hiện, không thực sự. AIComponent sẽ được tách riêng, như trong sơ đồ thứ hai. Nó sẽ không chứa các thành phần khác. Câu hỏi quan trọng hơn cho tình huống thứ hai của bạn là, nếu nhà thiết kế chỉ chọn các thành phần mà không có lập trình viên, làm thế nào để Thực thể biết khi nào cần thay đổi trạng thái? Các trạng thái khác nhau ngụ ý các trạng thái chuyển tiếp khác nhau - ai đó vẫn cần chỉ định những trạng thái đó.
Tesserex

Bạn có nghĩa là thêm AIComponent vào thực thể trong sơ đồ 2, điều này sẽ điều khiển Chân đế / Đi bộ / Xoay-Thành phần? Ý tưởng của tôi là các thành phần gửi tín hiệu khối hoặc kích hoạt theo các điều kiện nhất định. Ví dụ, SwingComponent sẽ phát ra các tín hiệu chung, ví dụ tín hiệu "ràng buộc" khi bắt đầu và "release_feet" khi kết thúc cú swing. WalkComponent sẽ vô hiệu hóa và tự kích hoạt dựa trên các tín hiệu này. Vì các 'chuyển trạng thái' được gói gọn trong chính các thành phần, nên người thiết kế sẽ không cần một lập trình viên nối các thành phần lại với nhau.
ma

@ghostonline Điều đó hoạt động tốt đối với những thứ có quy tắc cố định như "không thể đi trong khi đu" nhưng còn việc chuyển đổi giữa đứng và đi thì sao? Nếu đứng trong tầm kiểm soát, làm sao nó biết đi thử? Logic đứng có thể muốn chọn đi bộ hoặc xoay, bị ảnh hưởng bởi sự vắng mặt hoàn toàn của khả năng đi bộ - nó phải luôn luôn chọn để xoay trong trường hợp đó. Nhưng tôi nghĩ bạn đang đi đúng hướng.
Tesserex

2

Ít nhất tôi sẽ giữ Trình phát AI (hoặc cái mà tôi gọi là Trình điều khiển Trình phát) làm thành phần riêng của nó. Với hầu hết các trò chơi, người chơi về cơ bản đủ khác biệt với các NPC mà bạn không thể khái quát từ cái này sang cái khác ngoại trừ những điều cơ bản như điểm nhấn.

Đối với các NPC, tôi thấy StandComponent và WalkComponent là các khía cạnh của cùng một thứ. Bạn đã bao giờ có WalkComponent mà không có StandComponent chưa? Tôi nghi ngờ điều đó. Tương tự như vậy, RunComponent sẽ chỉ là một WalkComponent với tốc độ cao hơn và các hình ảnh động khác nhau. Tôi có thể thấy giá trị khi có NPCMovementComponent và NPCwordFighterComponent riêng biệt, nhưng ngay cả điều đó cũng cảm thấy như áp đảo tôi.


Tôi sẽ không tách rời phong trào NPC và phong trào người chơi nhiều như vậy. Các hành động chuyển động điều khiển hoạt hình và vật lý chắc chắn có thể được chia sẻ; đó là những gì chọn hành động hoặc chuyển tiếp khác nhau (người chơi nhận đầu vào trong khi AI là ... AI). Tôi đồng ý rằng bạn có Trình điều khiển Player, nhưng bạn cũng có Trình điều khiển AIC, cả hai đều có thể sử dụng Thành phần chuyển động / Thành phần xoay để thực hiện công việc hoạt hình / vật lý thực tế.
homebrew

Thật. Tôi giả định rằng tất cả các đối tượng chuyển động đều có PhysComponent hoặc MovementComponent xử lý chuyển động của chúng và PlayerContoder và AIContler sẽ sử dụng điều đó để xử lý chuyển động. Chuyển động chắc chắn phải là một thành phần riêng biệt, vì có thể có những thứ cần di chuyển không có AI hoặc có AI đơn giản nhất có thể (các vật thể câm như thùng hoặc rác).
Gregory Avery-Weir

2

Đầu tiên tôi sẽ tạo một thành phần Trạng thái và sau đó tôi sẽ tạo một máy trạng thái để xử lý các chuyển đổi. Làm cho nó đủ chung chung để bạn có thể sử dụng điều này cho người chơi và AI của bạn. Điều này sẽ đảm bảo AI chơi theo cùng một quy tắc và bạn không phải thay đổi logic của mình khi bạn thay đổi cách trạng thái của người chơi hoạt động so với trạng thái AI.

Máy trạng thái hữu hạn C ++

Ở trên có một ví dụ cụ thể về một máy trạng thái trong c ++ có thể được sử dụng bởi người chơi và cả AI.


1

Những gì bạn muốn là một thành phần xử lý chuyển động của các nhân vật (người chơi và NPC). Thành phần AI hoặc thành phần người chơi sẽ gửi lệnh đến thành phần chuyển động này và nó sẽ kiểm tra xem hành động có thể được bắt đầu hay không. Điều này sẽ gói gọn các ràng buộc chuyển động của bạn thành một thành phần duy nhất. Mã AI và mã trình phát của bạn không cần phải biết thanh kiếm được thực thi như thế nào. AI sẽ có các trạng thái nội bộ, ví dụ như Idle, Tấn công, Chạy trốn.


1
TYPO: "Nó sẽ nhận được ..." những gì từ thành phần AI?
Pup
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.