คำถามนี้คือ "ติดตาม" คำถามจากก่อนหน้านี้หนึ่งของฉันเกี่ยวกับการตรวจสอบการชนและความละเอียดที่คุณสามารถหาได้ที่นี่
หากคุณไม่ต้องการอ่านคำถามก่อนหน้านี่เป็นคำอธิบายสั้น ๆ เกี่ยวกับการทำงานของเครื่องมือฟิสิกส์ของฉัน:
ทุกหน่วยงานทางกายภาพจะถูกเก็บไว้ในคลาสที่เรียกว่า SSSPBody
รองรับเฉพาะ AABB
SSSPBody ทุกคนถูกเก็บไว้ในคลาสที่เรียกว่า SSSPWorld ซึ่งจะอัปเดตทุกตัวและจัดการกับแรงโน้มถ่วง
ทุกเฟรม SSSPWorld อัปเดตทุกส่วนของร่างกาย
ร่างกายที่ได้รับการปรับปรุงทุกตัวจะมองหาวัตถุที่อยู่ใกล้เคียงในพื้นที่ว่างเปล่าตรวจสอบว่าพวกเขาต้องการตรวจจับการชนหรือไม่ ถ้าใช่พวกเขาเรียกใช้เหตุการณ์ "การชนกัน" และตรวจสอบว่าพวกเขาต้องการแก้ไขการชนกันหรือไม่ ถ้าใช่พวกเขาจะคำนวณเวกเตอร์การเจาะและการเหลื่อมกันของทิศทางจากนั้นเปลี่ยนตำแหน่งเพื่อแก้ไขการแทรกซึม
เมื่อร่างกายชนกับวัตถุอื่นมันจะส่งผ่านความเร็วไปยังอีกความเร็วหนึ่งโดยการตั้งค่าความเร็วของร่างกายเป็นของมันเอง
ร่างกายคือความเร็วถูกตั้งค่าเป็น 0 เมื่อมันไม่ได้เปลี่ยนตำแหน่งจากเฟรมสุดท้าย หากมันชนกับตัวถังที่เคลื่อนไหว (เช่นลิฟต์หรือแพลตฟอร์มที่กำลังเคลื่อนที่) มันจะคำนวณความแตกต่างของการเคลื่อนไหวของลิฟต์เพื่อดูว่าร่างกายไม่ได้เคลื่อนที่จากตำแหน่งสุดท้ายหรือไม่
นอกจากนี้เนื้อความจะเรียกเหตุการณ์ "ทับซ้อน" เมื่อมุม AABB ทั้งหมดซ้อนทับบางสิ่งบางอย่างในกรอบ
นี้คือรหัสที่มาแบบเต็มของเกมของฉัน มันแบ่งออกเป็นสามโครงการ SFMLStart เป็นอินพุตการจัดการไลบรารีภาพวาดและการอัพเดตเอนทิตีที่ง่าย SFMLStartPhysics เป็นสิ่งที่สำคัญที่สุดโดยที่คลาส SSSPBody และ SSSPWorld นั้น PlatformerPhysicsTest เป็นโครงการเกมที่มีตรรกะของเกมทั้งหมด
และนี่คือวิธี "อัปเดต" ในคลาส SSSPBody แสดงความคิดเห็นและทำให้เข้าใจง่าย คุณสามารถดูได้เฉพาะที่นี้ถ้าคุณไม่รู้สึกเหมือนกำลังดูโครงการ SFMLStartSimplePhysics ทั้งหมด (และแม้ว่าคุณจะทำเช่นนั้นคุณควรจะดูสิ่งนี้ตั้งแต่มันแสดงความคิดเห็น)
. gif แสดงสองปัญหา
- หากร่างกายอยู่ในลำดับที่ต่างกันจะเกิดผลลัพธ์ที่แตกต่าง ลังด้านซ้ายจะเหมือนกันกับลังด้านขวาวางเฉพาะในลำดับผกผัน (ในตัวแก้ไข)
- ลังทั้งสองควรขับไปทางด้านบนของหน้าจอ ในสถานการณ์ด้านซ้ายไม่มีลังบรรจุอยู่ ด้านขวามีเพียงหนึ่งในนั้นเท่านั้น ทั้งสองสถานการณ์ไม่ได้ตั้งใจ
ปัญหาแรก: ลำดับของการอัพเดท
มันค่อนข้างง่ายที่จะเข้าใจ ในสถานการณ์ทางด้านซ้ายลังสูงสุดจะถูกอัพเดตก่อนสถานการณ์อื่น แม้ว่าลังที่ด้านล่าง "ถ่ายโอน" ความเร็วไปอีกอันหนึ่งมันต้องรอเฟรมถัดไปเพื่อเคลื่อนที่ เนื่องจากมันไม่เคลื่อนที่ความเร็วของลังด้านล่างจะถูกตั้งค่าเป็น 0
ฉันไม่รู้ว่าจะแก้ไขอย่างไร ฉันต้องการโซลูชันที่ไม่ต้องพึ่งพา "การเรียงลำดับ" รายการอัปเดตเนื่องจากฉันรู้สึกว่าฉันทำอะไรผิดพลาดในการออกแบบเครื่องมือฟิสิกส์ทั้งหมด
เอ็นจิ้นฟิสิกส์ที่สำคัญ (Box2D, Bullet, Chipmunk) ทำหน้าที่จัดการลำดับการอัปเดตอย่างไร
ปัญหาที่สอง: มีเพียงหนึ่งลังเท่านั้นที่ถูกส่งไปยังเพดาน
ฉันยังไม่เข้าใจว่าทำไมสิ่งนี้เกิดขึ้น สิ่งที่ "สปริง" ทำคือตั้งค่าความเร็วของร่างกายเป็น -4000 และจัดตำแหน่งใหม่บนสปริงเอง แม้ว่าฉันจะปิดการใช้งานรหัสตำแหน่งใหม่ปัญหายังคงเกิดขึ้น
ความคิดของฉันคือเมื่อลังด้านล่างชนกับลังด้านบนความเร็วจะถูกตั้งค่าเป็น 0 ฉันไม่แน่ใจว่าทำไมสิ่งนี้ถึงเกิดขึ้น
แม้จะมีโอกาสดูเหมือนคนที่ยอมแพ้ในปัญหาแรก แต่ฉันโพสต์ซอร์สโค้ดโครงการทั้งหมดข้างต้น ฉันไม่มีอะไรที่จะพิสูจน์ได้ แต่เชื่อฉันฉันพยายามอย่างมากที่จะแก้ไขปัญหานี้ แต่ฉันไม่พบวิธีแก้ปัญหาและฉันไม่เคยมีประสบการณ์มาก่อนเกี่ยวกับฟิสิกส์และการชน ฉันพยายามแก้ไขปัญหาทั้งสองนี้มานานกว่าหนึ่งสัปดาห์และตอนนี้ฉันหมดหวัง
ฉันไม่คิดว่าฉันจะหาทางแก้ปัญหาได้ด้วยตัวเองโดยไม่แยกคุณสมบัติมากมายออกจากเกม (เช่นการถ่ายโอนความเร็วและสปริงเป็นต้น)
ขอบคุณมากสำหรับเวลาที่ใช้ในการอ่านคำถามนี้และขอบคุณมากยิ่งขึ้นถ้าคุณลองหาวิธีแก้ปัญหาหรือข้อเสนอแนะ