Làm thế nào để xử lý va chạm đúng cách trong một trò chơi dựa trên thành phần?


11

Cố gắng quấn đầu tôi xung quanh các cách để xử lý va chạm đúng cách trong một trò chơi được thiết kế xung quanh các thành phần.

Tôi thấy nhiều ví dụ có một số loại PhysicsComponentđược thêm vào danh sách các thành phần của thực thể nhưng việc triển khai thực tế làm tôi bối rối.

Để làm việc này, PhysicsComponentsẽ cần truy cập vào thế giới xung quanh nó. Điều này không có ý nghĩa trực quan với tôi. Không phải một thành phần không nên biết về không chỉ container của nó (thực thể), mà cả container của nó (thế giới)?

Đối với tôi, có vẻ như cấp độ hoặc cảnh nên duy trì một danh sách các thực thể này và mỗi bản cập nhật trò chơi, lặp qua các thực thể để xác định va chạm nào.

Câu hỏi của tôi là thứ nhất, liệu đây có phải là thiết kế tốt hay không, và thứ hai, làm thế nào để xác định thực thể nào có thể va chạm. Tôi cho rằng các thực thể rắn có thể thực hiện giao diện IRigidBody trống để mức có thể xác định thực thể nào trong danh sách hỗ trợ xung đột. Nhưng điều này có phá vỡ thiết kế thành phần?

Thay vào đó, chúng có nên chứa một thành phần RigidBody trống không? Điều này thực sự có thể tốt hơn bởi vì nó có thể không phải lúc nào cũng trống rỗng và cách tiếp cận này là bằng chứng trong tương lai nhiều hơn. Vấn đề duy nhất với điều này là sự phức tạp. Cảnh sẽ phải lặp đi lặp lại không chỉ mọi thực thể, mà cả các thành phần của mọi thực thể để xác định xem nó có thành phần RigidBody này hay không.

Thứ ba, khi chúng va chạm cả hai thực thể nên được thông báo bằng cách nào đó và tôi không chắc chắn về cách thực hiện điều này.

Giả sử rằng cả hai thực thể đều chứa HealthComponent và khi chúng va chạm cả hai sức khỏe của chúng sẽ bị giảm đi bởi một số giá trị tùy ý, 5. Tôi cho rằng trách nhiệm của mình là xử lý việc này khi phát hiện va chạm giữa hai thực thể?

Nhưng sau đó là cảnh chịu trách nhiệm cho quá nhiều? Tôi có thể thấy điều này có thể thoát khỏi tầm tay và trở nên khó sử dụng khi cảnh chịu trách nhiệm cho nhiều thứ mà các thực thể không nên (?) Có quyền truy cập.

Chỉnh sửa: Câu hỏi cập nhật với nhiều chi tiết hơn.


4
Câu trả lời này có vẻ phù hợp để liên kết đến: gamedev.stackexchange.com/questions/13797/iêu
Andrew Russell

Câu trả lời được liên kết của Andrew, câu trả lời của James và câu trả lời của Nick Wiggill đều xứng đáng +1. Hãy nghĩ về các thành phần như dữ liệu hơn là một lớp thông thường có cả dữ liệu và phương thức (không phải là chúng sẽ không có phương thức, nhưng chúng không nên chịu trách nhiệm nhiều). Nhìn vào hệ thống thành phần Artemis ( piemaster.net/2011/07/entity-component-artemis ) để biết ví dụ về khung thành phần tốt.
michael.bartnett

Câu trả lời:


5

Thành thật mà nói, từ khía cạnh thiết kế thành phần của mọi thứ, các thành phần của tôi không biết về nhau trừ khi chúng phải (Và điều đó rất hiếm). Thậm chí sau đó tôi thường thích các thành phần nói chuyện với một số hệ thống quản lý các thành phần nói trên thay vì các thành phần trực tiếp. (Giao diện kịch bản trông giống như đối tượng của nó với đối tượng, nhưng nó không nằm trong công cụ thực tế, hehe).

Cuối cùng, tôi sẽ bên cạnh những gì bạn nói và đi với các thành phần vật lý tồn tại ở bất cứ nơi nào các vật thể cần được kiểm tra về sự va chạm của chúng. Bây giờ rõ ràng các đối tượng này có thể phải thông báo cho các thành phần khác của chính mình khi giải quyết va chạm, nhưng, như đã đề cập, đây là nơi tôi thích sự kiện chỉ để đi ra các đối tượng thông qua giao diện khác (cho người quản lý hoặc thông qua hệ thống nhắn tin sự kiện nếu bạn có một trong những ví dụ).

Tôi nghĩ rằng bạn đang đi đúng hướng và chỉ cần nhiều hơn một 'Có, điều đó nghe có vẻ đúng' Vì vậy, vâng, điều đó nghe có vẻ đúng.

Hi vọng điêu nay co ich!


3

Thông thường các công cụ trò chơi sử dụng thư viện của bên thứ 3 để phát hiện va chạm giữa các thực thể. Trong kịch bản đó, người ta tạo hoặc đăng ký những thực thể có Vật lý học vào thế giới "vật lý". Và bất cứ khi nào nó phát hiện ra sự va chạm giữa hai thực thể (A và B), thông thường nó sẽ gọi lại cho thực thể A thông báo rằng nó đã va chạm với thực thể B và tương tự cho thực thể B, thông báo rằng nó đã va chạm với thực thể A.

Đối với 2D, một thư viện vật lý miễn phí nổi tiếng là Box2D. Ngoài ra, cũng đáng để xem Chipmunk. Đối với 3D, Bullet là miễn phí (có thể là miễn phí tốt nhất bạn có thể tìm thấy). Havok và PhysX nổi tiếng vì được sử dụng trong rất nhiều trò chơi A A.


2

Vấn đề bạn gặp phải là khi phát hiện va chạm (đó là lý do duy nhất bạn cần một thực thể mang thành phần vật lý để tham chiếu một thực thể khác) được thực hiện ở cấp độ cao hơn, thường là do vòng lặp trò chơi của bạn trực tiếp hoặc bởi một hàm trợ giúp / lớp thực hiện điều này. Câu trả lời của tôi cho ai đó vài tuần trước nói về việc loại bỏ thực thể trên cơ sở tương tự và ghi nhớ rằng nếu một vụ va chạm làm cho một trong các thực thể của bạn bị phá hủy, thì câu trả lời tương tự, trong bối cảnh cụ thể của nó, sẽ rất phù hợp với bạn , vì một "quyền lực cao hơn" vẫn sẽ phải quản lý việc dọn dẹp các cơ thể ... có thể nói như vậy.

Làm bất kỳ điều này giữa các thực thể một mình, thường không khả thi. Gần như luôn luôn có một proxy cho những thứ như vậy, trong một kiến ​​trúc vững chắc, cho dù đó là thông qua quản lý trực tiếp như với phát hiện va chạm, hoặc gửi đi sự kiện như trong ví dụ. một hệ thống nhắn tin người chơi trong đó trình quản lý nhắn tin phía máy khách lắng nghe các tin nhắn được gửi từ người chơi và gửi chúng đến máy chủ để được phát lại cho mọi người.


2

Bây giờ tôi đang đối mặt với chính xác vấn đề giống như bạn trong một dự án. Cách tôi quyết định giải quyết nó là có một "ColliderComponent" giữ cơ thể từ động cơ vật lý. Các cơ quan được xác định bên ngoài (định nghĩa hình dạng được tải trong thời gian chạy) và sau đó được thêm vào thế giới vật lý các thực thể trò chơi mà chúng thuộc về.

Tôi đang sử dụng Box2D nơi bạn có thể đính kèm "trình lắng nghe va chạm" sẽ được thông báo bởi vụ va chạm. Vì tôi thêm một con trỏ vào "ColliderComponent" của mình vào dữ liệu người dùng của cơ thể, tôi có thể nhận được hai ColliderComponents của mình là một phần của xung đột.

Vì vậy, điều xảy ra khi xảy ra va chạm là như sau: ColliderComponents là một phần của vụ va chạm sẽ gửi tin nhắn đến đối tượng chủ sở hữu của chúng (thực thể trò chơi) sẽ lần lượt phát thông báo đó đến tất cả các thành phần của nó.

Mọi thành phần sau đó có thể phản ứng với thông điệp đó, vì vậy "thành phần sức khỏe" của bạn có thể loại bỏ 5 điểm khỏi sức khỏe, v.v.


+1: Tôi đang sử dụng một cách tiếp cận rất giống nhau. Làm thế nào để bạn xác định mức độ thiệt hại gây ra tùy thuộc vào loại thực thể va chạm?
Den

@ Tôi đã gửi các tin nhắn khác nhau (hoặc dữ liệu tin nhắn) theo sự va chạm đã xảy ra. Điều này hoạt động tốt với tôi, vì tôi không có nhiều trường hợp khác nhau để xử lý.
bummzack

0

Tạo một hệ thống va chạm biết "thế giới" va chạm. Sau đó, trong thành phần va chạm của bạn báo cho hệ thống va chạm để chiếu một tia từ điểm A đến B và phản hồi nếu nó va chạm hay không.

Chúc may mắn. Tôi thấy hệ thống va chạm là một trong những phần tẻ nhạt hơn của công cụ trò chơi.

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.