การตรวจจับการชนกันของภาพสามมิติ


11

ฉันมีปัญหาบางอย่างกับการพยายามตรวจจับการชนกันของไทล์สองภาพสามมิติ

ฉันได้ลองพล็อตเส้นระหว่างจุดแต่ละจุดบนไทล์แล้วตรวจสอบการสกัดกั้นเส้น แต่ไม่ได้ผล (อาจเป็นเพราะสูตรไม่ถูกต้อง)

หลังจากดูเรื่องนี้สักครู่วันนี้ฉันเชื่อว่าฉันกำลังคิดจะทำอะไรมากมายและจะต้องมีวิธีที่ง่ายกว่านี้

ฉันไม่ได้มองหารหัสเพียงแค่แนะนำวิธีที่ดีที่สุดในการตรวจจับการซ้อนทับ


4
คุณพยายามทำอะไร ตรวจสอบเมื่อเมาส์อยู่เหนือไทล์หรือตรวจหาว่ามีสองยูนิตซ้อนทับกันหรือไม่? หากภายหลังคุณควรนึกถึงการแยก "เกม" ของคุณออกจาก "กราฟิก"
John McDonald

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

คำตอบ:


23

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

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

แนวคิดทั่วไปคือโลกของเกมถูกเก็บไว้ในหน่วยความจำอย่างสมบูรณ์เบื้องหลังมันเป็นเพียงตัวเลขการอ้างอิงและตรรกะ ความจริงที่ว่าคุณกำลังวาดโลกของเกมในภาพวาดสามมิตินั้นไม่เกี่ยวข้อง โลกของเกมของคุณไม่ควรมีแนวคิดของภาพสามมิติหรือสี่เหลี่ยมหรือแม้ว่าหน้าจอจะถูกวาดเป็น 3D ทั้งหมดนี้ได้รับการดูแลเมื่อคุณวาดโลกของเกมไปที่หน้าจอ (หรือที่รู้จักในโลกของหน้าจอ ) โลกของเกมควรได้รับการจัดเก็บและดูแลรักษาด้วยวิธีที่ง่ายที่สุดซึ่งเหมาะสำหรับเกมในเกมที่มีมิติเท่ากันโดยทั่วไปคุณจะไม่สนใจข้อเท็จจริงที่ว่า iso นั้นและเก็บตำแหน่งไว้ราวกับว่าคุณใช้ตารางที่จัดเรียงตามแนวแกน เกมส่วนใหญ่จะมีวิธีการแปลงพิกัดระหว่างสองโลกที่ฉันเรียกว่าฉันScreenToWorld(x, y)และWorldToScreen(x, y). การแปลงมักจะทำกับคณิตศาสตร์เมทริกซ์ แต่สามารถทำได้ในวิธีอื่น คุณจะใช้ ScreenToWorld เมื่อคุณใช้เมาส์และ WorldToScreen เมื่อคุณวาด

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

FreeCivเป็นตัวอย่างที่ดีของสิ่งเหล่านี้ คุณสามารถดูโลกที่แน่นอนเช่นเดียวกับใด ๆ ของ: ตารางเหนือ / ใต้กริด, Isometric หรือแม้กระทั่ง Hex ทุกเกมที่คุณเรียกใช้มีเซิร์ฟเวอร์เฉพาะที่ทำงานในพื้นหลังแม้สำหรับเกมที่มีผู้เล่นคนเดียวดังนั้นลูกค้าจึงเป็นเพียงพอร์ตดิสเพลย์ไม่มีอะไรเพิ่มเติม

เรื่องสั้นที่มีความยาว: การแยกโลกของเกมและตรรกะออกจากหน้าจอทำให้ตรรกะของเกมง่ายขึ้นลดการแสดงผลเกม <-> การมีเพศสัมพันธ์และในทางกลับกันทำให้การตรวจจับการชนระหว่างแผ่น "iso" ง่ายต่อการจัดการ


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

1
สำหรับคนในอนาคต กราฟิคคือการตีความข้อมูล สี่ชิ้นหลักของเกม: ตรรกะข้อมูลอินพุตเอาต์พุต หลีกเลี่ยงการรวมเข้าด้วยกัน นอกจากนี้การตอบสนองที่ยอดเยี่ยม John, +1
Aarowaim

9

คำตอบของ John ค่อนข้างถูกต้อง แต่ฉันจะพยายามอธิบายในวิธีอื่น:

ไม่มีการตรวจจับการชนกันของภาพสามมิติ

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

มันเป็นคำถามเชิงปรัชญามากกว่านี้: ต้นไม้ล้มลงในป่าจริง ๆ แล้วยังชนกับพื้นดินหรือไม่เมื่อไม่มีใครอยู่ในนั้น?

ภูมิปัญญาดั้งเดิมจะพูดว่า: ใช่ ไม่สำคัญว่าคุณจะมองอย่างไร สิ่งต่าง ๆ ชนกันในอวกาศ - โลกไม่ใช่มุมมอง - อวกาศ


2
+1 เอาล่ะ "ไม่มีการตรวจจับการชนกันของภาพสามมิติ"
John McDonald

1
ขอบคุณฉันเพิ่งพูดในสิ่งที่คุณพูดไปแล้ว แต่แตกต่างกันเล็กน้อย
MarkR

0

คุณสามารถลองจัดสรรอาร์เรย์ของพิกเซลที่ประกอบด้วยบิตแมปของแต่ละค่า getRGB () ของแต่ละพิกเซล เปรียบเทียบกับค่าที่มีคำสั่ง if เป็นเส้นขอบของกระเบื้องเป็นค่าสีแยกต่างหากจากค่าของสิ่งที่กระเบื้องแสดง (น้ำทรายหญ้า) นั่นสำหรับตารางภาพสามมิติพื้นฐาน หรือคุณสามารถมีแผนที่สองชั้น เลเยอร์หนึ่งที่มีการเรียงลำดับเช่นหน้าจอสีเขียววาดโครงร่างของตัวแทนของวัตถุที่ชนกันและเลเยอร์อื่นจะเป็นแผนที่เอง

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

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

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