การชน 2d ที่รวดเร็วและแม่นยำ


17

ฉันกำลังทำงานกับปืน topdown 2d และตอนนี้ต้องไปไกลกว่าระบบพื้นฐานการชนกล่องสี่เหลี่ยมของฉัน

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

ฉันวางแผนที่จะรับมือกับการชนดังต่อไปนี้:

  1. ตรวจสอบว่าสไปรต์ใด ๆ อยู่ในระยะของเครื่องเล่นหรือไม่
  2. ทำการทดสอบการชนกันของกล่องสี่เหลี่ยม
  3. ทำการชนที่ถูกต้อง (ที่ฉันต้องการความช่วยเหลือ)

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

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

คำตอบ:


18
  1. ขั้นตอนที่หนึ่งสร้างตารางและอัปเดตสำหรับทุกวัตถุที่เคลื่อนไหว
  2. ตรวจสอบการชนกันของวัตถุในช่องสี่เหลี่ยมเดียวกันเท่านั้น
  3. ตรวจสอบว่ากล่องขอบเขตของวัตถุตัดกันหรือไม่ (ประกอบด้วยสี่เหลี่ยม)
  4. ตรวจสอบการชนกันของพิกเซลที่สมบูรณ์แบบโดยใช้โครงร่างความละเอียดต่ำ (ดูเกมฟิสิกส์)
  5. ตรวจสอบการติดตามโครงร่างตามปกติตามที่อธิบายไว้ใน Game Physics (Q 2)

ขั้นตอนที่ 1:

สร้างอาร์เรย์ grid 2d วัตถุทุกชิ้นรู้ว่ากำลังสองซึ่งมันครอบครองโดยตำแหน่ง x, y และความกว้างและความสูง หากวัตถุถูกย้ายออกไปวัตถุนั้นจะถูกลบออกจากจัตุรัสเก่าและอัพเดทสี่เหลี่ยมใหม่ที่มันกำลังครอบครอง

การดำเนินการนี้จะรวม O (n) ทั้งหมดสำหรับวัตถุ n เท่านั้น สำหรับวัตถุเฉพาะใด ๆ O (1)

ขั้นตอนที่ 2:

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

ขั้นตอนที่ 3:

ตรวจสอบจุดตัดระหว่างวัตถุสี่เหลี่ยม หากไม่มีทางแยกให้หยุด

ขั้นตอนที่ 4:

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

โปรดอ่านสิ่งนี้สำหรับแนวคิดเกี่ยวกับวิธีแบ่งโลกของเกมออกเป็นกริดสแควร์ส:

สร้างระบบตรวจจับการชนที่มีประสิทธิภาพ

โปรดอ่านสิ่งนี้เพื่อปรีชาเกี่ยวกับวิธีตรวจจับพิกเซลที่สมบูรณ์การชนของ

เกมฟิสิกส์ / 2D ตรวจจับการชนกัน AS3

คุณสามารถปรับปรุงประสิทธิภาพอย่างมีนัยสำคัญ:

  1. การบันทึกโครงร่างเวอร์ชันความละเอียดต่ำ (1/16) เพื่อตรวจสอบก่อน

  2. ตรวจสอบเฉพาะในพื้นที่ที่ rects สองจุดตัดกัน

  3. โดยการแบ่งร่างคร่าว ๆ ออกเป็นเซ็กเมนต์และตรวจสอบการชนกันของเซ็กเมนต์ก่อนเท่านั้น

กรุณารู้สึกยินดีที่จะแสดงความคิดเห็นและฉันจะทำอย่างละเอียด

ตรวจสอบในบริเวณสี่แยก


1
ดังที่อาร์เธอร์กล่าวว่าให้แทนที่ขั้นตอนที่ 1 และ 2 ของคุณด้วยเส้นตารางและสำหรับการตรวจจับการชนกันที่แม่นยำคุณสามารถใช้รูปภาพที่มีความละเอียดต่ำ
Markus von Broady

1
และถ้าคุณต้องการจริงๆคุณสามารถใช้เทคนิคคล้ายกับคำตอบของฉันที่นี่: gamedev.stackexchange.com/questions/38481//
Markus von Broady

มาร์คัสชี้ให้เห็นความคิดที่ดี คุณควรใช้อาเรย์ 2d-boolean หรืออาเรย์ 1d ที่ถือว่าเป็น 2d และคุณสามารถบันทึกเวอร์ชัน 1/2 1/4 1/8 low-res ของอาเรย์นั้นเพื่อเพิ่มความเร็ว สิ่งนี้อาจไม่จำเป็นเนื่องจากการคำนวณในอาร์เรย์ 2d-boolean นั้นรวดเร็วมาก มันยังคงเป็นเครื่องมือที่มีประโยชน์
wolfdawn

หากผู้เล่นมีอยู่ทั้งหมดภายในหนึ่งตารางในตารางคุณสามารถตรวจสอบเฉพาะกับวัตถุในตารางนั้น ผู้เล่นอาจจะอยู่ในสี่สี่เหลี่ยมที่อยู่ติดกันในครั้งเดียว นั่นคือสิ่งที่คุณหมายถึงอะไร หากคุณหมายถึงจุดตัดระหว่างสี่เหลี่ยมใช่คุณเพียงแค่ต้องตรวจสอบการชนถ้าพวกมันตัดกัน
wolfdawn

1
ฉันหวังว่าการอัปเดตจะช่วยให้สิ่งต่าง ๆ ชัดเจนขึ้น เมื่อคุณมีโค้ดที่เขียนคุณสามารถโพสต์มันในการตรวจสอบรหัสและเชื่อมโยงเราสำหรับความคิดเห็น codereview.stackexchange.com
wolfdawn
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.