การตรวจจับการชนกันแบบ 2 มิติสำหรับเกมพินบอล


9

จนถึงตอนนี้ในเกมก่อนหน้านี้ฉันใช้การชนสองมิติแบบง่ายกับกล่องจากนั้นตรวจสอบที่ระดับพิกเซลเพื่อการชนกัน

หากทำเกมพินบอลในเฟรมจำนวนมากลูกจะสัมผัสกับกำแพงหรือพื้นผิวอื่นดังนั้นจะมีวิธีอื่นหรือไม่?

คำตอบ:


19

ย้อนกลับไปในสมัย ​​(1990) เกมพินบอลเก่าสร้างขึ้นเช่นนี้:

มีหลายเลเยอร์สำหรับ playfield (สิ่งที่คุณเห็นเมื่อเล่นเกม):

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

และหลายเลเยอร์สำหรับการชน:

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

ภาพสีเทาด้านซ้ายเป็นแผนที่การชนกันของเกมหลักภาพด้านขวาเป็นแผนที่การชนสำหรับพื้นที่พิเศษ: ทางลาดพินบอล

White = พื้นที่ว่างสำหรับลูกบอลดัชนีสีมี 255

Gray= ball จะถูก "ผลักออกไป" จากโซนนี้ ดัชนีสี = มุมของเวกเตอร์เพื่อเพิ่มไปยังตำแหน่งลูก สีเทาอ่อน = 0 องศา สีเทาเข้ม = 360 องศา

โค้ดหลอกบางอย่าง:

void do_ball_physics()
{
    while(1)
    {
         byte color = read_pixel_under_ball(ballx, bally); //one pixel read
         if(color == 255) //see remark below
            break;
         float vectorx = sin(color/255.0f * 2.0f * PI);
         float vectory = cos(color/255.0f * 2.0f * PI); 
         ballx += vectorx; //push ball away from one unit
         bally += vectory; //

    }
}

บางดัชนีสีพิเศษนอกจากนี้ยังสามารถนำมาใช้สำหรับสิ่งอื่นมากกว่าการชนกันช่วงสีที่กำหนดเอง (เช่น: 240-255) สามารถสงวนไว้สำหรับการตรวจสอบโซนพิเศษเช่นspinners, triggers, bumpers, holes...

อย่างที่คุณเห็นนี่มันง่ายมาก มีพิกเซล "อ่าน" เพียงไม่กี่พิกเซลต่อหนึ่งเฟรม ด้วยเหตุนี้คุณสามารถทำให้การจำลองทางฟิสิกส์ทำงานในอัตราเฟรมที่สูงจริงเช่น: 200 fps การใช้อัตราเฟรมสูงจะทำให้การจำลองราบรื่นและลด "การขุดอุโมงค์" (เกิดขึ้นเมื่อลูกบอลวิ่งเร็วเกินไปและผ่านองค์ประกอบรางโดยไม่เกิดการชนกัน) ความเรียบง่ายนั่นก็เป็นสิ่งที่ทำให้เกมพินบอลราบรื่นเป็นไปได้ใน386 computers(และเร็วกว่า286) ย้อนกลับไปในอดีต (ท่ามกลางเทคนิคอื่น ๆ เช่นการขี่จักรยานสีการเลื่อน vga และการปิดบังสไปรต์ ... )

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

ตัวอย่าง (จากเบาะสำหรับปักเข็มภาพ ):

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

บาง บริษัท เกมใช้เครื่องยนต์ฟิสิกส์ของตัวเอง แต่อีกวิธีที่ง่ายคือการใช้เครื่องมือทางฟิสิกส์เช่นหรือBox2D Bulletเกมพินบอลสำหรับ iPhone ส่วนใหญ่ที่ฉันเห็นอยู่นั้นใช้เอนจิ้นฟิสิกส์ที่มีอยู่แล้ว + สินทรัพย์ 3 มิติ


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

1
แผนที่การชนกันสามารถจัดเก็บในอาร์เรย์ทำไมคุณต้องการจัดเก็บไว้ในผืนผ้าใบบางส่วน? ดังที่คุณได้กล่าวไปแล้วส่วนแรกของคำตอบนั้นส่วนใหญ่จะเป็นประวัติ แต่ถ้าคุณต้องการใช้พินบอลในซีพียูที่มี end ต่ำมาก (เช่น: gsm เก่า) มันยังคงใช้ได้ ในยุคปัจจุบันฉันอยากจะแนะนำให้ใช้เครื่องมือฟิสิกส์เช่น jbox2d หรือทำฟิสิกส์ด้วยตัวเองด้วยการชนกับส่วนของเส้นหรือเส้นโค้งเบซิเยร์ (ถ้าคุณคิดว่าคุณสามารถเขียนสิ่งนี้ได้)
tigrou

การอ่านพิกเซลในภาพเป็นไปอย่างรวดเร็วมากในเบราว์เซอร์สมัยใหม่ บางส่วนของ "omg JS แรกเร็วกว่า C" การสาธิตทั้งหมดเป็นเมล็ดในการประมวลผลภาพ
Sean Middleditch

คุณเรียนรู้เกี่ยวกับแผนที่ปะทะได้อย่างไร?
Bemmu

1
เนื่องจากข้อผิดพลาดนี้ทำให้ความฝันรีเมค: pouet.net/prod.php?which=24499 (ไม่ใช่ฉัน) ดูที่แหล่งข้อมูลแผนที่การชนกันของข้อมูลที่ฉันพูดถึง
tigrou

1

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

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


ทำไมคุณถึงบอกว่าการตรวจจับการชนกันของภาพ 3 มิติสิ่งนี้เป็นชุดที่มีมากกว่า 2D?
จอห์น

@ จอห์นฉันคิดว่าเกมพินบอลที่ดีเป็นเกมสามมิติที่มีทางลาด ฯลฯ คุณสามารถตั้งโปรแกรมทางลาดเหล่านี้ในแบบ 2D และไต่ระดับลูกบอลขึ้นเมื่อมันข้ามทางลาดและลงเมื่อมันถอยกลับตัวคุณเอง แต่ในกรณีนี้มันยังคงเป็น 3D เกมคุณเพียงแค่เพิ่มมิติ Z ด้วยตัวเอง
Markus von Broady

1

ฉันทำเกมพินบอลเมื่อไม่นานมานี้ มันเป็นพิกเซลเช่นกัน ฉันมีแผนที่การชนซึ่งเพิ่งมีข้อมูลการชน การชนกันโดยประมาณนั้นหาง่าย:

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

หวังว่าจะให้ความคิดกับคุณ :)


1

ก่อนอื่นถ้าคุณสร้างเกมพินบอลคุณน่าจะต้องการการตรวจจับการชนแบบวงกลมมากกว่าการใช้ BOX 1 :-)
เนื่องจากความซับซ้อนของฟิสิกส์ที่เกี่ยวข้องกับพินบอลเต็มเปี่ยมผมขอแนะนำให้ดู เอนจิ้น 2D ฟิสิกส์ที่มีอยู่ Box2D ค่อนข้างมีชื่อเสียงในจาวาสคริปต์อาจจะมีคนอื่น แต่ฉันก็ไม่ได้เจอดี (และฟรี) อันใดอันหนึ่ง
Rq1: แน่นอนว่าคุณใช้การแบ่งแบบดั้งเดิมในเกมของคุณระหว่างการอัพเดทและการจับคู่ และคุณใช้ตัวจับเวลา (setInterval / setTimeout) และ / หรือ RequestAnimationFrame เพื่อเรียกการอัปเดตแล้ววาดตามปกติ พินบอลอาจเป็นประเภทของเกมที่คุณต้องการอัปเดตตัวจับเวลาการขับขี่หนึ่งครั้งและการขับอีกครั้งเพื่อให้คุณสามารถปรับอัตราของแต่ละเกมได้อย่างอิสระเพื่อทำงานกับอุปกรณ์ที่หลากหลาย เนื่องจากคุณไม่สามารถปล่อย (อัปเดต + วาด) หากอุปกรณ์ช้าเกินไป: ถ้าเวลาระหว่างการอัพเดตสองครั้ง (dt) ยาวเกินไปเอ็นจิ้นฟิสิกส์อาจพลาดการชน


0

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

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