Nếu hai đối tượng tương tác, cái gì giữ mã tương tác?


28

Hãy nghĩ về một viên đạn và một kẻ thù, hoặc người chơi và sàn nhà. Nếu các đối tượng này tương tác, cái gì giữ mã tương tác?


2
Tương tác theo cách nào? Bạn có nghĩa là phát hiện va chạm? Nếu vậy thì rất có thể bạn sẽ triển khai cả lớp phát hiện va chạm và trình quản lý giải quyết va chạm.
CaptainRedmuff

Một phần là có, tôi quan tâm đến cả vụ va chạm và những gì xảy ra sau vụ va chạm. Viên đạn có kiểm tra xem nó có gần với kẻ thù không, hay ngược lại? Và chuyện gì xảy ra sau vụ va chạm, một vật thể đạn có thể nói với đối tượng kẻ địch bị trúng đạn không? Như bạn có thể thấy tôi khá bối rối về tất cả mọi thứ, và nó làm cho một số mã rất khó đọc.
ThatOneGuy

Câu trả lời:


23

TL; DR:

Các đối tượng trò chơi của bạn không biết về nhau và họ cũng không thực hiện kiểm tra đối với các đối tượng khác. Bạn tạo một mô hình phát hiện va chạm và giải quyết va chạm để kiểm tra các đối tượng trò chơi của bạn và thực hiện các hành động thích hợp để mô phỏng vật lý trò chơi của bạn.

Đồ đạc tốt

Từ những nỗ lực trước đây trong việc viết phát hiện va chạm và đọc cuốn sách này , có hai giai đoạn để phát hiện va chạm và giải quyết va chạm. Giai đoạn đầu tiên (phát hiện va chạm) là một đường chuyền sớm, nơi bạn xác định xem hai đối tượng có thể có va chạm tiềm năng hay không. Nếu bất kỳ hai đối tượng nào tạo thành va chạm tiềm năng, thì bạn sẽ chuyển các đối tượng này sang giai đoạn thứ hai (độ phân giải va chạm) để chạy kiểm tra hạt mịn hơn đối với các đối tượng và cố gắng giải quyết va chạm.

Ở đâu đó trong công cụ / trò chơi của bạn, bạn sẽ nắm giữ một loạt tất cả các đối tượng trong thế giới của bạn. Trên mỗi khung hình, bạn sẽ lặp qua mảng và kiểm tra từng đối tượng với mọi đối tượng khác bằng một phát hiện va chạm hộp / hình cầu giới hạn đơn giản.

Mã giả:

dectectCollisions(objects)
{
    for(objectA in objects)
    {
        for(objectB in objects)
        {
            if(objectA != objectB) //ignore self
            {
                if(BoundingSpheresIntersect(objectA, objectB))
                {
                    collisionResolver.addObjects(objectA, objectB);
                }
            }
        }
    }
}

Kiểu vòng lặp này khá kém hiệu quả nhưng không có chỗ để cải thiện thông qua việc sử dụng phân vùng không gian như là một sự khởi đầu cho các đối tượng được đảm bảo cách nhau quá xa để va chạm.

Sau khi kiểm tra hai vật thể có va chạm tiềm năng (tức là cả hai vật thể đủ gần để va chạm), các vật thể được truyền đi để thực hiện thói quen phát hiện va chạm chính xác hơn.

Hãy tưởng tượng bạn có hai đa giác có hình dạng và kích thước ngẫu nhiên đủ gần để có thể giao nhau nhưng không phải do hình dạng của chúng:

Hình ảnh được tìm thấy qua google

Sử dụng các quả cầu giới hạn, hai vật thể này sẽ tạo ra dương tính giả cho một vụ va chạm tiềm năng. Đây là nơi sau đó bạn sẽ thực hiện một đường chuyền kỹ lưỡng hơn để xác định xem hai đối tượng có thực sự giao nhau hay không.

Khi bạn đã tìm thấy một vụ va chạm thực sự, bước giải quyết va chạm của bạn sẽ thực hiện hành động thích hợp để giải quyết các đối tượng bằng cách áp dụng các lực hoặc khoảnh khắc tùy thuộc vào độ chi tiết và nhu cầu của vật lý trò chơi của bạn.

Với suy nghĩ này, bạn có thể trừu tượng hóa toàn bộ quá trình phát hiện và giải quyết va chạm để các đối tượng của bạn không cần biết gì về nhau, cũng như quá trình cần thiết để xác định và giải quyết va chạm. Hai lớp / người quản lý xử lý việc này cho bạn chỉ cần biết các thuộc tính cơ bản của từng đối tượng để thực hiện kiểm tra nhanh và bẩn cho các va chạm và sau đó cần phải kiểm tra kỹ hơn.


2
Đặc biệt, mẫu thiết kế của Người hòa giải sẽ phù hợp. Mẫu Observer sẽ là một lựa chọn tốt, có ý định rất khác. Bạn có thể nhận được một bản tóm tắt khá hay về chúng trên bài đăng Stackoverflow này .
kurtzbot

12

Một cách Unreal Engine 3 xử lý nó:

Viên đạn nhận được một tin nhắn va chạm nói rằng nó bắn trúng thứ gì đó, với một cuộc tranh luận cho nó biết nó đã bắn trúng cái gì. Sau đó, nó có thể gọi objectHit.takeDamage (tự). Sau đó, mục tiêu nhận được thông báo TakeDamage, với một con trỏ trỏ tới thứ đánh vào nó và thực hiện hành động thích hợp.

Cá nhân tôi thích cách tiếp cận này vì nó có nghĩa là viên đạn có thể thực hiện các hành động đặc biệt (như tạo ra một loại hiệu ứng nổ tùy thuộc vào loại vật trúng) và mục tiêu có thể thực hiện các hành động đặc biệt tùy thuộc vào loại đạn.

Cũng có khả năng viên đạn biết nó làm gì để nhắm mục tiêu và có thể gọi chức năng trên nó, như objectHit.freeze (tự). Sau đó, mục tiêu biết rằng nó đã bị tấn công bởi thứ gì đó đóng băng nó, và đó là loại vật thể gì.

EDIT: Câu trả lời này có nghĩa là một bức tranh chung về cách nó có thể hoạt động, vì có lẽ bạn không làm việc với UE3. :)


10

Thief đã làm điều này rất tốt trong Dark Engine với Nguồn và Receptron. Một đối tượng có thể có cả hai thuộc tính này, với các loại khác nhau. Ví dụ: mũi tên Nước sẽ có Nguồn cho WaterStim khi tiếp xúc. Một vụ nổ sẽ có AoE FireStim.

Khi Mũi tên nước chạm vào một đối tượng, đối tượng mục tiêu sau đó tìm kiếm Receptron của nó để tìm bất cứ thứ gì tìm kiếm WaterStim với các giá trị cường độ phù hợp. Sau đó, nó thực thi bất kỳ lệnh nào được liên kết với nó (trong trường hợp này, biến một ngọn đuốc đang cháy thành một ngọn đuốc tắt và phát ra một luồng khói.)

Vì cùng một động cơ được sử dụng trong SystemShock2, đây là cách xử lý tất cả các loại sát thương khác nhau, các viên đạn khác nhau có bộ Stims khác nhau và các quái vật khác nhau có Receptron cho các loại Kích thích khác nhau và gây sát thương bằng 1 *, 2 *, 1 / 2 cường độ tùy thuộc vào loại đạn có "siêu hiệu quả" hay không.

Nó có vẻ như là một hệ thống rất linh hoạt khi bạn có thể thêm nguồn và thụ thể vào các đối tượng trong trình chỉnh sửa cấp độ, (để tạo một cửa một lần mở nếu bị lửa, nói.) Trong khi bạn cũng có thể nói với một thụ thể để "gửi tập lệnh thông báo "nếu đối tượng có các tập lệnh đặc biệt liên quan đến nó.

Những gì bạn không muốn làm là phải mã hóa một ma trận tương tác nXn của tất cả các đối tượng có thể va chạm với tất cả các đối tượng có thể! Bằng cách khái quát hóa các tương tác thông qua các thông điệp được tiêu chuẩn hóa, bạn đơn giản hóa quy trình.


Từ quan điểm kịch bản, cách tiếp cận này có vẻ linh hoạt nhất và biểu cảm nhất. Rất tuyệt.
drhayes

-2

Một giải pháp là giữ các thùng chứa đạn và người chơi trong các lớp riêng biệt, và sau đó có chức năng main () giữ cho vòng lặp khung chịu trách nhiệm tương tác.

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.