ควรวางตรรกะการตรวจจับการชนกันที่ไหน


19

ฉันกำลังพัฒนาเอ็นจิ้นเกม 2D ขนาดเล็ก ตัวละครมีวิธีทาสีซึ่งปัจจุบันทำดังต่อไปนี้:

  1. คำนวณตำแหน่งใหม่ของตัวละครตามความเร็ว ฯลฯ
  2. อัปเดตเซลล์กริดการชน **
  3. วาดตัวละครที่ตำแหน่งใหม่

** ฉันได้สร้างตารางการชนกันเพื่อลดจำนวนการตรวจสอบทางแยก

ตอนนี้อัลกอริทึมพื้นฐานที่ฉันคิดว่าตรวจจับการชนกันคือ:

For Each Character
    Check intersection with characters in surrounding 8 cells

ฉันสามารถวางรหัสนี้ในวิธีการทาสี แต่นี่คือปัญหาที่ฉันคาดหวัง

สมมติว่าอักขระสองตัว A และ B อยู่ในเซลล์ที่อยู่ติดกันในตารางการชนกัน ตอนนี้ตามอัลกอริทึมข้างต้นในการวนซ้ำของอักขระ A มันจะตรวจพบว่ามันชนกับ B ในการวนซ้ำสำหรับอักขระ B มันจะตรวจจับว่ามันชนกับ A

แต่ฉันมีความคิดว่าเมื่อ A ตรวจพบว่ามันชนกับ B มันควรแจ้ง B ว่ามันชนกับ A นี่จะช่วยประหยัดการเปรียบเทียบได้มากเมื่อมีนักแสดงมากกว่า 2 คนชนกัน แต่ฉันไม่แน่ใจว่าจะจัดการเรื่องนี้อย่างไร ฉันคิดว่าแทนที่จะตรวจสอบการชนกันของตัวละครทุกตัวฉันควรตรวจสอบการชนภายในวงเกม

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


ฉันเสียใจที่ได้ Nitpick แต่ในห้องสมุดฟิสิกส์ 2D แบบพิเศษ โดยปกติแล้วฟิสิกส์ของเกมจะมีความใกล้เคียงดังนั้นวิธีแก้ปัญหาใด ๆ ที่ทำให้เกมที่เล่นไม่ได้นั้นเป็นเรื่องปกติ แต่ถ้าคุณต้องการที่จะแก้มันอย่างถูกต้องให้ใช้ฟิสิกส์พิเศษเช่น Box2D ... :-D
user712092

คำตอบ:


14

วิธีการตามปกติสำหรับการตรวจจับการชนคือไม่มี A หรือ B ตรวจจับการชนกันด้วยตนเอง

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

ดังนั้นในสาระสำคัญแทนที่จะทำ "ย้ายตรวจสอบการชนวาด" ภายในฟังก์ชัน Paint () ของคุณคุณแบ่ง "ย้าย" และ "วาด" เป็นฟังก์ชันแยกต่างหากซึ่งคุณเรียกใช้แยกต่างหาก (ก่อน "ย้าย" สำหรับวัตถุทุกชิ้นจากนั้น "วาด" สำหรับทุกวัตถุ) และระหว่างนั้นให้ตรวจสอบการชนกัน

หมายเหตุขั้นสูง: หากวัตถุใด ๆ ของคุณเคลื่อนย้ายตัวเองเพื่อตอบสนองต่อการชนที่ตรวจพบคุณอาจต้องทำซ้ำขั้นตอน "ค้นหาการชนกันระหว่างวัตถุทุกคู่" ในกรณีที่การตอบสนองการชนของวัตถุทำให้เกิดการชนกันอีกครั้ง


นี่เป็นวิธีที่เหมาะสมในการทำสิ่งต่าง ๆ ให้วัตถุจัดการกับความรับผิดชอบของตนและระบบการชนควรตัดสินใจว่าจะเกิดอะไรขึ้นเมื่อพวกเขาเจอสิ่งกีดขวาง นอกจากนี้คุณยังสามารถมีรูปสี่เหลี่ยมผืนผ้าชน / รูปทรงกระบอก (2d / 3d) รอบตัวละครของคุณเป็นทริกเกอร์
James P.

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

วิธีจัดการกับสิ่งนี้ - gamedev.stackexchange.com/questions/13076/…
Cracker

1

ฉันใช้วนรอบสำหรับตัวละครทั้งหมดของฉันในลูปเกมอย่างที่คุณพูด

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

ฉันใส่โค้ดที่มีผลกระทบในลูปดังนั้นการกระทำใด ๆ ที่ควรทำใน B เกิดขึ้นใน A's loop ดังนั้นจึงไม่มีเหตุผลใดที่ B จะต้องตรวจสอบเพราะนี่จะทำให้ผลของการชนกันนี้อาจแตกต่างกันสำหรับคุณ .


แต่ในกรณีนี้เมื่อ A ตรวจพบจุดตัดด้วย B จะมีการตั้งค่า B.hit เป็นจริงดังนั้น B จะไม่ตรวจสอบจุดตัดใด ๆ แต่ถ้าตัวละครอื่น C ตัดกับ B, B จะไม่ตรวจจับเหรอ?
Cracker

ขออภัยเข้าใจแล้ว เนื่องจาก A ไม่ตัดกับ C ดังนั้น C.hit จะยังคงเป็นเท็จ B จะไม่ตรวจสอบการชน แต่ C จะตรวจสอบและจะส่งข้อมูลไปยัง B ว่ามีการชนกันระหว่าง B และ C Cool!
Cracker

แต่ฉันเดาว่า A, B และ C ตัดกันซึ่งกันและกันจะมีปัญหาไหม A จะทำให้ B.hit และ C.hit เป็นจริง B และ C จะรู้ว่าพวกเขาชนกับ A แต่เนื่องจากคุณสมบัติการโจมตีของพวกเขาเป็นความจริงพวกเขาจะไม่ตรวจสอบการชนกัน การปะทะกันระหว่าง B และ C จะไม่มีใครสังเกตเห็น
Cracker

คุณสามารถแอบเข้าไปในวิธีการที่คล้ายกันได้โดยการวางวัตถุการชนกันทั้งหมดในคอลเล็กชั่นบางประเภทจากนั้นตรวจสอบการชนกับสิ่งที่อยู่หลังวัตถุในคอลเลกชันเท่านั้น IE: A เช็คกับ B, C, D; ตรวจสอบ B กับ C, D; การตรวจสอบ C กับ D แต่ละอันไม่จำเป็นต้องตรวจสอบเนื่องจากมีการตรวจสอบแล้วจากที่อยู่เบื้องหลังการเลี้ยว ไม่เร็วเท่ากับการข้ามการชนขององค์ประกอบทั้งหมด แต่มีประโยชน์อย่างไรก็ตาม
Lunin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.