ในเกมแข่งรถ 3 มิติที่ง่ายมากการชนกันจะจัดการอย่างไร


9

ฉันสงสัยว่าการชนในเกมแข่งรถ 3 มิติแบบเรียบง่ายทำได้อย่างไร (โดยเฉพาะในเกมอย่าง Outrun 2 / Motoracer)

ในเกมแข่งรถคลาสสิกที่มีสภาพแวดล้อมที่ซับซ้อน (โลกเปิด) ฉันคิดว่านี่เป็นกล่องพื้นฐาน (สำหรับรถยนต์) เพื่อชนเครื่องบิน (สำหรับแทร็ก สิ่งทั้งหมดจะได้รับการปรับให้เหมาะสมโดยใช้กล่องขอบเขต (นี่คือวิธีการชนกันของเกมในหลาย ๆ เกม)

ในเกมอย่าง Outrun 2 / Motoracer การเล่นเกมนั้นง่ายมากที่ผู้พัฒนาอาจไม่ต้องการและทุกอย่างก็ง่ายขึ้นมาก สำหรับผู้ที่ไม่เคยเล่นนี่คือสิ่งที่เฉพาะเจาะจงมาก:

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

นี่คือวิธีที่ฉันคิดว่ามีการปะทะกัน (อาจ):

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

จากนั้นจัดการกับการชน (และดึงรถ):

1) ค้นหาตำแหน่งที่ใกล้เคียงที่สุดบนเส้นโค้ง 3 มิติจากตำแหน่งรถ 3 มิติปัจจุบัน กล่าวอีกนัยหนึ่งเปลี่ยนตำแหน่งรถ 3 มิติให้เป็นตำแหน่งเส้นโค้งที่ดี ทุกตำแหน่ง 3 มิติบนท้องถนนอาจถือได้ว่าเป็นการกระจัดไปตามเส้นโค้ง 3 มิติ ( t) + การกระจัดด้านข้าง ( d) ตรวจสอบภาพด้านล่างหากไม่ชัดเจน (นี่เป็นตัวอย่าง 2d แต่สิ่งนี้ใช้ได้กับ 3d ได้อย่างง่ายดาย)

ป้อนคำอธิบายรูปภาพที่นี่

เมื่อ t = 0 รถอยู่ที่ส่วนเริ่มต้นของแทร็กเมื่อ t = 1 รถอยู่ที่จุดสิ้นสุด เมื่อ d = -1 หรือ 1 รถอยู่ที่ขอบของแทร็กเมื่อ d = 0 รถอยู่ตรงกลางถนน

2) จัดรถให้ตรงกับถนนโดยใช้tและd(ง่ายมาก: สำหรับค่าใด ๆtและdค่าฉันสามารถรับตำแหน่ง 3 มิติ + เวกเตอร์ขึ้น / ด้านหน้า / ซ้าย) ตอนนี้รถติดอยู่บนถนน

3) ตรวจสอบการเคลื่อนที่ด้านข้างdของรถยนต์ หากค่ามีขนาดใหญ่เกินไป(d > 1)หรือ(d < -1)รถต่ำอยู่นอกเส้นทาง เพียงแค่คลิปมันเพื่อวางรถในตำแหน่งที่ถูกต้อง

นอกจากนี้ยังทำให้ 3d เลือกสรรง่ายมากเพียงแค่วาดติดตามจากรถปัจจุบันตำแหน่งที่จะtt + some_big_enough_value_to_avoid_visible_clipping

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

คำตอบ:


16

ฉันได้ทำงานในเกมเชิงพาณิชย์สองสามแบบที่คล้ายคลึงกับเกมที่คุณอธิบาย

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

แต่ด้วยสิ่งที่กล่าวมาเรายังทำสิ่งที่คุณระบุไว้ในส่วนที่ฉันคิดว่าการชนจะทำงานเพื่อป้องกันการชนของอุโมงค์ / บกพร่องและระบบนี้ก็ถูกใช้อย่างหนักสำหรับการแข่งตรรกะ AI นอกจากนี้เรายังใช้มันเพื่อระบุว่ารถยนต์คันใดที่เป็นผู้นำเพื่อให้เราสามารถแสดงสัญลักษณ์ "1st / 2nd / 3rd / etc" บน HUD บางครั้งข้อมูลนี้ก็ใช้สำหรับการตอบโต้รถหลังจากเกิดการชนครั้งใหญ่

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

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

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

คำอธิบายการเลือกสรรของคุณให้คำอธิบายพื้นฐานที่ดีเกี่ยวกับวิธีใช้ spline แต่จริงๆแล้วมันซับซ้อนกว่าที่คุณแนะนำ - ถ้าคุณใช้ splines สำหรับการคัดแบบนี้กิ๊บยาว ๆ มักจะไม่วาดด้านตรงข้าม ของการเลี้ยวเนื่องจากเมื่อวัดจากระยะทางตามแนวขวางฝั่งตรงข้ามของการเลี้ยวอาจอยู่ไกลมากแม้ว่าจะอยู่ห่างออกไปเพียงไม่กี่เมตรเมื่อวัดเป็นอีกาบิน. นอกจากนี้ระยะทางที่โลกเรขาคณิตสามารถมองเห็นได้มักจะแตกต่างจากที่รางตาข่ายสามารถมองเห็นได้ดังนั้นสิ่งเหล่านี้จึงไม่เหมาะกับระบบนี้เช่นกัน ประสบการณ์ของฉันคือในกรณีส่วนใหญ่จะดีกว่าที่จะไม่ใช้ตรรกะติดตามต่อไปนี้เพื่อพิจารณาว่าควรวาดโมเดลหรือไม่ มีความน่าเชื่อถือมากขึ้นและทำให้มีความผิดพลาดน้อยลงในการใช้การทดสอบ frustum ของกล้องมาตรฐานสำหรับสิ่งนั้น


ให้ข้อมูลและสนุกกับการอ่านคำตอบ
onedayitwillmake

0

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


ดูเหมือนว่าคุณจะอธิบายเกม 2 มิติ (วงกลมชนด้วยสีของพิกเซล) มันเป็นอย่างนั้นเหรอ? จากนั้นคำตอบคือ offtopic
Kromster

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