การชนกันของข้อมูล


23

ฉันรู้วิธีตรวจสอบการชนได้ค่อนข้างดี แต่ฉันไม่รู้วิธีจัดการการชนในวิธีที่ดี

ประยุกต์ได้ง่ายถ้าวัตถุสองชิ้นชนกันฉันใช้การคำนวณบางอย่างเพื่อเปลี่ยนทิศทางความเร็ว หากฉันไม่ย้ายวัตถุทั้งสองพวกเขาจะยังคงทับซ้อนกันและหากความเร็วไม่ใหญ่พอพวกเขาจะยังคงชนกันหลังจากอัปเดตครั้งถัดไป สิ่งนี้อาจทำให้วัตถุติดกัน

แต่ถ้าฉันพยายามย้ายวัตถุทั้งสองดังนั้นพวกเขาจึงไม่ทับซ้อนกัน ฟังดูเป็นความคิดที่ดี แต่ฉันรู้ว่าถ้ามีวัตถุมากกว่าสองชิ้นสิ่งนี้จะซับซ้อนมาก ถ้าฉันย้ายวัตถุสองชิ้นและหนึ่งในนั้นชนกับวัตถุอื่นดังนั้นฉันต้องย้ายมันด้วยและพวกเขาอาจชนกับกำแพงเป็นต้น

ฉันมีเกม 2D บนลงล่างในใจ แต่ฉันไม่คิดว่าจะเกี่ยวข้องกับมันมากนัก มักจะมีการชนกันอย่างไร

คำถามนี้ถูกถามในนามของ Wooh


1
คุณช่วยอธิบายประเภทของเกมได้หรือไม่? "บนลงล่าง 2D" อาจหมายถึงสิ่งต่าง ๆ มากมาย: เกมแอ็คชั่นผจญภัยสไตล์เซลด้า, นักกีฬาแนวตั้งเลื่อนหรือเกมบิลเลียดพกพา ทั้งหมดนี้จะมีรูปแบบมาตรฐานที่แตกต่างกันมากในการจัดการการชน!
Ian Schreiber

2
ฉันไม่สามารถอธิบายได้อย่างชัดเจน คำถามไม่ได้เกี่ยวกับสิ่งที่จะเกิดขึ้นจากการชน แต่เป็นการจัดการกับปัญหาการทับซ้อนหลายครั้ง ฉันคิดว่ามันเพียงพอที่จะรู้ว่าฉันตีกลับวัตถุซึ่งกันและกันและฉันต้องการให้พวกเขาประพฤติตนตามความเป็นจริงเพื่อตอบคำถามนี้
CiscoIPPhone

คำตอบ:


16

แดเนียล Kodicek ครอบคลุมหัวข้อนี้ในรายละเอียดมากในหนังสือของเขาคณิตศาสตร์และฟิสิกส์สำหรับโปรแกรมเมอร์

Kodicek ทำสองสิ่งเพื่อให้ได้ความละเอียดของการชนที่ดูเป็นธรรมชาติ:

  • ฟังก์ชั่นตรวจจับการชนของเขาจะคำนวณเวลาที่แน่นอนที่วัตถุสองชิ้นจะชนกัน
  • เขาคำนวณความเร็วใหม่ในเวลาที่เกิดการชนดังนั้นวัตถุจึงไม่ทับซ้อนกัน

ฉันอัปโหลดสาธิตขึ้นอยู่กับการตรวจสอบการชน Kodicek และความละเอียด

อัปเดต:ต่อไปนี้เป็นอัลกอริธึมการตรวจหาการชน & ความละเอียดที่คล้ายกับวิธีของ Kodicek ด้วยรหัสที่มา ฉันยังคงแนะนำหนังสือของ Kodicek เนื่องจากอัลกอริทึมของเขานั้นมีการใช้งานที่แตกต่างกันเล็กน้อยและอธิบายอย่างละเอียดมากยิ่งขึ้น


1
ลิงก์สาธิตของคุณดูเหมือนจะใช้งานไม่ได้
ashes999

@ ashes999: แก้ไขลิงก์แล้ว!
Leftium

มันเป็นอัลกอริทึมสำหรับแวดวง แล้วกล่องล่ะ?
Anton Chikin

@AntonChikin: อัลกอริธึมการแก้ปัญหาการชนของ Kodicek ใช้เพียงสามอินพุต: มวลความเร็วและปกติที่จุดชน Kodicek คำนวณค่าปกติ ณ จุดชนเสมอเมื่อตรวจจับการชน เขาอธิบายการตรวจจับการชนกันหลายประเภทรวมถึงกล่องที่ชนกล่องอื่น เพียงเสียบอัลกอริทึมการตรวจจับการชนกันของข้อมูลเข้ากับอัลกอริธึมการแก้ปัญหาการชนกันของข้อมูล ดูบทที่ 8-10 ของหนังสือของ Kodicek สำหรับคำอธิบายแบบเต็ม (หมายเหตุฟิสิกส์การหมุนต้องใช้คณิตศาสตร์มากกว่าซึ่งจะกล่าวถึงในภายหลังในหนังสือ ... )
Leftium

1
@ThomasHilbert: ซอร์สโค้ดตัวอย่างและโปรแกรมปฏิบัติการ Windows มีวางจำหน่ายแล้วที่leftium.com/asteroid
Leftium

6

ถ้าคุณตรวจสอบการชนก่อนที่วัตถุจะเคลื่อนที่แทนที่จะเป็นหลังจากนั้น หรืออีกนัยหนึ่งคุณปฏิเสธตำแหน่งใหม่ถ้าวัตถุชนกันนำของเก่ามาใช้ใหม่ในกรณีนั้นหรือไม่?

pseudocode:

  tmpPosition1 = Obj1.position
  tmpPosition2 = Obj2.position
  updatePosition(Obj1)
  updatePosition(Obj2)
  if collided(Obj1,Obj2) then
      updateVelocities( Obj1, Obj2 )
      Obj1.position = tmpPosition1
      Obj2.position = tmpPosition2
  endif

วิธีนี้วัตถุจะชนกันเมื่อพวกเขากำลังจะชนกันถ้าขั้นตอนการอัพเดตของคุณมีขนาดเล็กพอที่ผู้เล่นไม่ควรสังเกตเห็นสิ่งแปลก ๆ ในการเป็นตัวแทน


1
สิ่งนี้ค่อนข้างน่ารำคาญเพราะคุณไม่สามารถเคลื่อนที่ขนานกับวัตถุได้อย่างง่ายดายเพราะคุณไม่สามารถเคลื่อนย้ายที่หน้าจอหากคุณสัมผัสวัตถุอื่น
Ikke

เว้นแต่คุณจะแก้ไข x และ y แยกต่างหาก
instantaphex

6

เมื่อใดก็ตามที่วัตถุสองชิ้นซ้อนทับกันให้ตรวจสอบว่าวัตถุนั้นเคลื่อนที่ไปทางหรือออกจากกันหรือไม่ ทำการชนกันก็ต่อเมื่อพวกมันเคลื่อนที่เข้าหากัน

มันค่อนข้างง่ายกับคณิตศาสตร์เวกเตอร์เพียงคำนวณ:

dot_product (B.position - A.position, A.velocity - B.velocity)

หากผลลัพธ์เป็นค่าบวกวัตถุจะเลื่อนไปทางกันและกัน


4

ฉันอาจเข้าใจผิด แต่ดูเหมือนว่าคุณกำลังถามคำถามสองข้อ: 1. วิธีทั่วไปในการจัดการกับการแก้ไขการชนคำที่คุณกำลังมองหาคือ 'การจำลองตามแรงกระตุ้น' และมีเอกสารมากมายที่ สามารถทำมันได้ดีกว่าความยุติธรรม

โดยสรุปคุณต้องการที่จะเริ่มขั้นตอนการจำลองทางฟิสิกส์ของคุณในพื้นที่โมเมนตัมซึ่งก็คือมวลคูณความเร็ว

สำหรับการตอบสนองเชิงมุมโชคดีที่ช่วงเวลาที่ยิ่งใหญ่ที่สุดและน้อยที่สุดของความเฉื่อยสามารถลดลงเป็นสองแกน orthogonal (ใน 2D) ซึ่งหมายความว่าเมทริกซ์ทวีคูณจะทำงานโดยทั่วไปและถ้าคุณเรียงแถวเหล่านี้กับแกน X และ Y เวกเตอร์ 2D

เมื่อคุณมีการชนคุณจะต้องตอบสนองโดยอิงตามช่วงเวลาเชิงเส้นและเชิงมุม ณ จุดปะทะและปัจจัยฟัดจ์ที่ดีคือถ้าคุณมีการแทรกซึมเพื่อใช้กำลังปรับ (ตามที่กล่าวไว้ข้างต้น) เพื่อแยกร่างทั้งสองออกจากกัน

จากจุดนี้คุณจะต้องเพิ่มกฎมากขึ้นเรื่อย ๆ เพื่อควบคุมพฤติกรรมที่ผิดปกติเช่นการกำหนดโมเมนตัมเชิงมุมสูงสุดเพื่อให้สิ่งต่าง ๆ ไม่หมุนเหมือนท็อปส์ซู ฯลฯ แต่นี่เป็นการเริ่มต้นที่ดี

ทำให้มันง่ายถ้าคุณทำได้

  1. คุณจะแก้ปัญหาการชนกันของร่างกายได้อย่างไร

วิธีเดียวที่แท้จริงในการทำเช่นนี้คือระบบสมการเชิงเส้นและการแก้ปัญหามากมาย วิธีปฏิบัติที่เป็นไปได้คือมีระบบเหมือนข้างบนและให้ฟิสิกส์แก้ปัญหาตามธรรมชาติเมื่อเวลาผ่านไป

เกมส่วนใหญ่ที่ทำสิ่งต่าง ๆ เช่นกลิ้งหรือยืนอยู่บนพื้นผิวที่เคลื่อนไหวมีรูปแบบไฮบริดที่เท้าของคุณติดอยู่กับพื้นผิว (หรือล้อไปตามถนน) เพื่อรองรับเวลาก้าวของฟิสิกส์ (ซึ่งจะส่งผลให้วงจร จะไม่ทำงาน)

หวังว่านี่จะช่วยได้ หากคุณต้องการตัวอย่างทางคณิตศาสตร์ใด ๆ แจ้งให้เราทราบ


3

วิธีนี้มักจะได้รับการแก้ไขในเครื่องยนต์ฟิสิกส์คือการใช้กำลังปรับ การขยับตัวที่แข็งหลังจากการสอดใส่ระหว่างกันจะไม่ดูดีถ้าร่างกายที่แข็งของคุณเคลื่อนที่ด้วยความเร็วสูงกว่า (คุณจะเห็นการเคลื่อนไหวกระตุกชั่วขณะ) แม้ว่าเป็นขั้นตอนแรกคุณควรลองและดูว่ามันเหมาะสมกับความต้องการของคุณหรือไม่

A penalty forceถูกนำไปใช้เช่นสปริงแดมเปอร์ซึ่งแรงลงโทษเพิ่มขึ้นยิ่งคุณเจาะร่างกายที่แข็งตัวและลดลงในเฟรมถัดไป คิดว่ามันเป็นสปริง เมื่อสองร่างแข็งระหว่างเจาะพวกเขาแต่ละคนเผชิญหน้าฤดูใบไม้ผลิที่มองไม่เห็นซึ่งช่วยลดความก้าวหน้าของพวกเขา (นั่นคือป้องกันมากขึ้นระหว่างการเจาะ) และนำไปใช้ที่กล่าวถึงก่อนหน้านี้penalty forceจนกว่าร่างกายจะไม่เจาะอีกต่อไป

มันเป็นหัวข้อกว้าง ๆ แต่หวังว่าข้อมูลข้างต้นจะช่วยให้คุณเริ่มต้นได้


ดังนั้นแทนที่จะป้องกันการแทรกซึมระหว่างวิธีนี้อนุญาต แต่ให้ความต้านทานเกือบเหมือนวัตถุที่ถูกบีบอัด?
CiscoIPPhone

มันให้ความต้านทานใช่ความต้านทานจะเพิ่มมากขึ้นเมื่อร่างกายพยายามเจาะ ในทางปฏิบัติหากคุณมีเวลาเดลต้าต่ำพอ (ตัวอย่างเช่น 10ms) จะไม่ทำให้เกิดการแทรกซึมระหว่างกัน ข้อดีที่แท้จริงของวิธีนี้คือเมื่อคุณมีเนื้อความที่แทรกซึมระหว่างกันด้วยเหตุผลต่าง ๆ (ตำแหน่งถูกเปลี่ยนพวกมันเป็นเครือข่ายร่างกายที่แข็งและตำแหน่งถูกแก้ไข) และตอนนี้ต้องแยกจากกันเพราะไม่มีเทคนิคนี้ร่างกาย จะระเบิดออกแทนที่จะแยกออกทีละน้อย
Samaursa
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.