Nếu tôi biết một hành động nhất định sẽ dẫn đến va chạm, tôi có nên cho phép hành động đó xảy ra không?


7

Tôi đã hoàn thành việc lập trình công cụ trò chơi của mình và bây giờ tôi đã thử nghiệm nó, tôi đã nhận thấy một số vấn đề về đồ họa.

Vấn đề lớn là khi người chơi cố gắng đẩy vào tường, nhân vật của họ sẽ "lắc lư" chống lại nó khi nó liên tục cố gắng xâm nhập vào không gian của bức tường và phát hiện va chạm liên tục đẩy nó ra bên ngoài.

Cách thích hợp để xử lý một tình huống như vậy là gì?

Bản năng đầu tiên của tôi là, nếu di chuyển theo một hướng nhất định gây ra va chạm, hãy vô hiệu hóa chuyển động theo hướng đó cho đến khi vị trí của thực thể thay đổi. Tức là, một khi một vật thể rơi xuống một nền tảng, vô hiệu hóa trọng lực cho đến khi vật thể không còn ở trên một nền tảng.

Có cách nào tốt hơn để giải quyết các phát hiện va chạm lặp đi lặp lại giữa hai đối tượng trong cùng một không gian chồng chéo không?

Câu trả lời:


5

Ví dụ về các va chạm ký tự với một bức tường (ví dụ: tôi sẽ sử dụng một số giá trị tùy ý): nếu bạn cách tường 10 đơn vị (ví dụ pixel) và một bước thường sẽ di chuyển bạn 20 đơn vị theo hướng đó, hành vi đúng là để nhân vật của bạn di chuyển 10 đơn vị và dừng lại ở đó. Nếu bạn đã hủy hành động thay vào đó, bạn sẽ ở cách tường 10 đơn vị không phải là điều bạn muốn.

Một cách để làm điều này là di chuyển nhân vật theo toàn bộ số lượng, sau đó phát hiện va chạm và độ sâu của nó, tức là bao nhiêu hộp giới hạn của nhân vật và bức tường chồng lên nhau, và di chuyển nhân vật trở lại với cùng một lượng đó. Nếu bạn làm điều này một cách chính xác, bạn sẽ không nhận được bất kỳ hành vi "lắc lư" nào từ nhân vật của mình, anh ta sẽ chỉ ấn vào tường và dừng lại ở đó. Nếu anh ta lắc lư thì có lẽ bạn đã đẩy anh ta trở lại quá nhiều (có lẽ bạn đang di chuyển anh ta trở lại vị trí anh ta trước khi va chạm, thay vì kẹp nó vào ranh giới tường).

Điều đó đang được nói, tôi thường thấy trọng lực được coi là một trường hợp đặc biệt. Trong hầu hết các triển khai tôi đã thấy, nhân vật lưu một onFloorcờ và trọng lực chỉ được áp dụng khi cờ đó là sai.

Chỉnh sửa: Tôi đoán bạn có thể mở rộng khái niệm cuối cùng này và tạo cờ bổ sung như touchingRightWallhay touchingLeftWall, nhưng chỉ khi ranh giới của các nhân vật và tường trận đấu chính xác . Trong trường hợp đó, bạn có thể bỏ qua chuyển động hoàn toàn. Nhưng nếu các ranh giới không khớp chính xác, bạn nên để chuyển động diễn ra và để hệ thống phát hiện va chạm giải quyết mọi giao lộ.


Đó là cách tôi xử lý va chạm, hiện tại. "Cái lắc lư" trông giống như sprite đang rung hơn là một lượng tiến / lùi có thể phát hiện được.
Raven Dreamer

2
Bạn đang tính toán độ sâu giao lộ chính xác? Cố gắng gỡ lỗi các giá trị vị trí của nhân vật và độ sâu giao nhau với các giá trị mà bạn mong muốn có. Tôi đã làm điều này trước đây mà không có rung động nào cả. Cũng có thể là một số trường hợp của vấn đề dấu phẩy động subpixel? Nếu đó là trường hợp, hãy thử làm tròn các giá trị của bạn. Và cuối cùng, hãy kiểm tra mẫu platformer của XNA.
David Gouveia

Thành thật mà nói, tôi nghĩ rằng đó chỉ là do IO (di chuyển thực thể) xảy ra vào thời điểm khác với phát hiện Collision, có nghĩa là hai thực thể trùng nhau cho đến khi công cụ trò chơi đến vòng lặp cập nhật của hệ thống con va chạm.
Raven Dreamer

Nhưng không phải các hệ thống con phát hiện va chạm IO và được cập nhật trong cùng một vòng lặp của vòng lặp cập nhật của bạn? Cách duy nhất tôi có thể thấy điều này tạo ra sự khác biệt là nếu vòng lặp kết xuất của bạn hoàn toàn tách biệt và bằng cách nào đó có thể được gọi giữa các bản cập nhật hệ thống con của bạn hoặc nếu bạn kéo dài quá trình xử lý này giữa một số khung.
David Gouveia

Toàn bộ quá trình thường sẽ là [IO -> Phát hiện va chạm -> Độ phân giải va chạm] -> [Kết xuất]. Ngay cả khi các phần Cập nhật và Kết xuất được gọi ở các mức khác nhau, bạn sẽ không bao giờ có thể thấy các đối tượng của mình được hiển thị ở một số trạng thái trung gian (ví dụ sau IO nhưng trước Phát hiện va chạm hoặc sau Phát hiện va chạm nhưng trước Giải quyết va chạm). Bạn sẽ luôn thấy nhân vật của mình được hiển thị sau khi tất cả các giai đoạn Cập nhật đã được áp dụng, do đó, không quan trọng là họ có được xử lý theo các bước khác nhau hay không.
David Gouveia

2

Vấn đề này thường xảy ra khi mã kẹp vị trí trước khi phát hiện va chạm. I E:

MoveCharacter();
ClampPosition();
CheckCollision();
DrawFrame();

thay vì

MoveCharacer();
CheckCollision();
ClampPosition();
DrawFrame();

Lý do nó "cười khúc khích" là vì kiểm tra xảy ra sau khi nhân vật được kẹp vào vị trí "an toàn", nhưng vì nhân vật ở vị trí không va chạm tại thời điểm kiểm tra, động cơ cho phép nhân vật tiếp tục di chuyển, sau đó nhân vật được vẽ và sau đó khung tiếp theo kiểm tra thất bại, Kẹp được gọi, khiến nhân vật "chụp" trở lại vị trí an toàn.


1
Tôi không thực sự thấy điều này có ý nghĩa như thế nào. Làm thế nào kẹp có thể xảy ra trước khi kiểm tra va chạm nếu bạn cần kết quả từ va chạm của mình để biết được giá trị nào sẽ kẹp ở vị trí đầu tiên?
David Gouveia

Có gì thực sự xảy ra là nhân vật đã được rút ra trước khi được chuyển đến đúng vị trí trên cạnh khung thay vì được chuyển đến đúng vị trí trước khi các hiện khung được rút ra.
Casey

0

Gần đây tôi đã gặp vấn đề tương tự và đã khắc phục nó như thế này:

di chuyển đối tượng, kiểm tra va chạm, nếu tìm thấy va chạm, đặt đối tượng bên ngoài đối tượng va chạm. vẽ đối tượng.

Người chơi có thể tiếp tục chạy vào tường mà không có bất kỳ tiếng cười nào vì trước khi rút ra, anh ta sẽ được đặt ở bên cạnh của vật thể.


0

Sử dụng toán học vectơ / mặt phẳng, bạn có thể tính toán chính xác điểm va chạm với tường sẽ xảy ra trong khung tiếp theo. Điều này giả định rằng nhân vật của bạn có vận tốc mà bạn có thể sử dụng để tính toán vectơ chuyển động sẽ xảy ra trong khung hình tiếp theo. Sau khi tìm thấy điểm va chạm, bạn có thể điều chỉnh vectơ trượt sẽ di chuyển nhân vật của bạn dọc theo bức tường, vectơ này thực sự có thể va chạm với một bức tường khác.

Vì vậy, trở lại câu hỏi của bạn, bạn nên tính toán vị trí va chạm chính xác nơi nhân vật của bạn sẽ được đặt và những gì thực sự nên xảy ra sau đó. Nếu đây là một bức tường và trò chơi FPS của nó, thì hãy để nhân vật trượt dọc theo 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.