Câu hỏi này là một câu hỏi "tiếp theo" từ câu hỏi trước của tôi, liên quan đến phát hiện và giải quyết va chạm, mà bạn có thể tìm thấy ở đây .
Nếu bạn không muốn đọc câu hỏi trước, đây là một mô tả ngắn gọn về cách thức hoạt động của động cơ vật lý của tôi:
Mỗi thực thể vật lý được lưu trữ trong một lớp gọi là SSSPBody.
Chỉ AABB được hỗ trợ.
Mỗi SSSPBody được lưu trữ trong một lớp gọi là SSSPWorld, cập nhật mọi cơ thể và xử lý trọng lực.
Mỗi khung hình, SSSPWorld cập nhật mọi cơ thể.
Mọi cơ quan cập nhật tìm kiếm các cơ thể gần đó trong hàm băm không gian, kiểm tra xem họ có cần phát hiện va chạm với chúng không. Nếu có, họ gọi một sự kiện "va chạm" và kiểm tra xem họ có cần giải quyết va chạm với họ không. Nếu có, họ tính toán vectơ thâm nhập và chồng chéo hướng, sau đó thay đổi vị trí của chúng để giải quyết sự thâm nhập.
Khi một cơ thể va chạm với người khác, nó sẽ chuyển vận tốc của mình sang người khác bằng cách đơn giản đặt vận tốc của cơ thể về phía mình.
Một cơ thể là vận tốc được đặt thành 0 khi nó không thay đổi vị trí từ khung cuối cùng. Nếu nó cũng va chạm với một cơ thể chuyển động (chẳng hạn như thang máy hoặc nền tảng di chuyển), nó sẽ tính toán độ chênh lệch chuyển động của thang máy để xem liệu cơ thể đó có di chuyển khỏi vị trí cuối cùng không.
Ngoài ra, một cơ thể gọi một sự kiện "bị nghiền nát" khi tất cả các góc AABB của nó chồng lên một cái gì đó trong một khung.
Đây là mã nguồn ĐẦY ĐỦ của trò chơi của tôi. Nó được chia thành ba dự án. SFMLStart là một thư viện xử lý đầu vào đơn giản, vẽ và cập nhật các thực thể. SFMLStartPhysics là lớp quan trọng nhất, trong đó các lớp SSSPBody và SSSPWorld. PlatformerPhysicsTest là dự án trò chơi, chứa tất cả logic trò chơi.
Và đây là phương thức "cập nhật" trong lớp SSSPBody, được nhận xét và đơn giản hóa. Bạn chỉ có thể xem xét điều này nếu bạn không muốn nhìn vào toàn bộ dự án SFMLStartSimplePhysics. (Và ngay cả khi bạn làm thế, bạn vẫn nên xem cái này vì nó đã được nhận xét.)
.Gif cho thấy hai vấn đề.
- Nếu các cơ thể được đặt theo một thứ tự khác nhau, kết quả khác nhau xảy ra. Các thùng bên trái giống hệt các thùng bên phải, chỉ được đặt theo thứ tự nghịch đảo (trong trình chỉnh sửa).
- Cả hai thùng phải được đẩy về phía trên cùng của màn hình. Trong tình huống bên trái, không có thùng nào được đẩy. Ở bên phải, chỉ có một trong số họ là. Cả hai tình huống đều ngoài ý muốn.
Vấn đề đầu tiên: thứ tự cập nhật
Điều này khá đơn giản để hiểu. Trong tình huống bên trái, thùng trên cùng được cập nhật trước cái khác. Ngay cả khi thùng ở phía dưới "chuyển" vận tốc sang cái khác, nó vẫn cần đợi khung tiếp theo di chuyển. Vì nó không di chuyển, vận tốc của thùng phía dưới được đặt thành 0.
Tôi không có ý tưởng làm thế nào để khắc phục điều này. Tôi muốn giải pháp không phụ thuộc vào việc "sắp xếp" danh sách cập nhật, bởi vì tôi cảm thấy mình đang làm gì đó sai trong toàn bộ thiết kế động cơ vật lý.
Làm thế nào để các động cơ vật lý chính (Box2D, Bullet, Chipmunk) xử lý thứ tự cập nhật?
Vấn đề thứ hai: chỉ có một thùng được đẩy lên trần nhà
Tôi chưa hiểu tại sao điều này xảy ra. Những gì thực thể "mùa xuân" làm là đặt vận tốc của cơ thể thành -4000 và đặt lại vị trí của nó trên đỉnh của lò xo. Ngay cả khi tôi vô hiệu hóa mã định vị lại, vấn đề vẫn xảy ra.
Ý tưởng của tôi là khi thùng phía dưới va chạm với thùng trên cùng, vận tốc của nó được đặt thành 0. Tôi không chắc tại sao điều này lại xảy ra.
Mặc dù có cơ hội trông giống như một người bỏ cuộc ở vấn đề đầu tiên, tôi đã đăng toàn bộ mã nguồn dự án ở trên. Tôi không có bất cứ điều gì để chứng minh điều đó, nhưng tin tôi đi, tôi đã cố gắng khắc phục điều này nhưng tôi không thể tìm ra giải pháp và tôi không có bất kỳ kinh nghiệm nào trước đây về vật lý và va chạm. Tôi đã cố gắng giải quyết hai vấn đề này trong hơn một tuần và bây giờ tôi đang tuyệt vọng.
Tôi không nghĩ rằng tôi có thể tự mình tìm ra giải pháp mà không cần loại bỏ nhiều tính năng ra khỏi trò chơi (ví dụ như chuyển tốc độ và lò xo).
Cảm ơn rất nhiều vì đã dành thời gian đọc câu hỏi này, và cảm ơn nhiều hơn nữa nếu bạn thậm chí cố gắng đưa ra một giải pháp hoặc một gợi ý.