จนถึงตอนนี้ในเกมก่อนหน้านี้ฉันใช้การชนสองมิติแบบง่ายกับกล่องจากนั้นตรวจสอบที่ระดับพิกเซลเพื่อการชนกัน
หากทำเกมพินบอลในเฟรมจำนวนมากลูกจะสัมผัสกับกำแพงหรือพื้นผิวอื่นดังนั้นจะมีวิธีอื่นหรือไม่?
จนถึงตอนนี้ในเกมก่อนหน้านี้ฉันใช้การชนสองมิติแบบง่ายกับกล่องจากนั้นตรวจสอบที่ระดับพิกเซลเพื่อการชนกัน
หากทำเกมพินบอลในเฟรมจำนวนมากลูกจะสัมผัสกับกำแพงหรือพื้นผิวอื่นดังนั้นจะมีวิธีอื่นหรือไม่?
คำตอบ:
ย้อนกลับไปในสมัย (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 มิติ
Pinballs มีชุดฟิสิกส์ที่เข้มข้นมากไม่เพียง แต่รูหรือกำแพงเท่านั้น แต่ยังมีปฏิกิริยาตอบสนอง (ตีกลับ) หรือพื้นผิวที่ไม่เรียบซึ่งลูกบอลช้าลงและได้รับความเร็วกลับคืนมา
หากคุณต้องการสร้างเบาะสำหรับปักเข็มที่ดีวิธีในการไปคือใช้การตรวจจับการชนกันแบบสามมิติหรือระบบที่ปรับให้เหมาะกับตัวเองสำหรับทุกวัตถุที่ชนกันได้ซึ่งมีวิธีที่มีพารามิเตอร์ระยะทางและความเร็ว
ฉันทำเกมพินบอลเมื่อไม่นานมานี้ มันเป็นพิกเซลเช่นกัน ฉันมีแผนที่การชนซึ่งเพิ่งมีข้อมูลการชน การชนกันโดยประมาณนั้นหาง่าย:
ใช้พื้นที่ของแผนที่การชนกันของลูกบอลที่ทับซ้อนกันค้นหาศูนย์กลางสร้างเวกเตอร์จากจุดนั้นไปที่ศูนย์กลางบอลจากนั้นทำให้เป็นมาตรฐาน
หวังว่าจะให้ความคิดกับคุณ :)
ก่อนอื่นถ้าคุณสร้างเกมพินบอลคุณน่าจะต้องการการตรวจจับการชนแบบวงกลมมากกว่าการใช้ BOX 1 :-)
เนื่องจากความซับซ้อนของฟิสิกส์ที่เกี่ยวข้องกับพินบอลเต็มเปี่ยมผมขอแนะนำให้ดู เอนจิ้น 2D ฟิสิกส์ที่มีอยู่ Box2D ค่อนข้างมีชื่อเสียงในจาวาสคริปต์อาจจะมีคนอื่น แต่ฉันก็ไม่ได้เจอดี (และฟรี) อันใดอันหนึ่ง
Rq1: แน่นอนว่าคุณใช้การแบ่งแบบดั้งเดิมในเกมของคุณระหว่างการอัพเดทและการจับคู่ และคุณใช้ตัวจับเวลา (setInterval / setTimeout) และ / หรือ RequestAnimationFrame เพื่อเรียกการอัปเดตแล้ววาดตามปกติ พินบอลอาจเป็นประเภทของเกมที่คุณต้องการอัปเดตตัวจับเวลาการขับขี่หนึ่งครั้งและการขับอีกครั้งเพื่อให้คุณสามารถปรับอัตราของแต่ละเกมได้อย่างอิสระเพื่อทำงานกับอุปกรณ์ที่หลากหลาย เนื่องจากคุณไม่สามารถปล่อย (อัปเดต + วาด) หากอุปกรณ์ช้าเกินไป: ถ้าเวลาระหว่างการอัพเดตสองครั้ง (dt) ยาวเกินไปเอ็นจิ้นฟิสิกส์อาจพลาดการชน
คุณอาจลองดูภาพพินบอลเปรียบเทียบกับอนาคตพินบอลสำหรับหัวข้อ 2d กับ 3d หากคุณเล่นพินบอลแบบเห็นภาพ (ทุกอย่างทำในแบบ 2d) จากนั้นเล่นพินบอลในอนาคตหรือสิ่งที่คล้ายกับ Zen Pinball คุณจะรู้สึกถึงความแตกต่างในวิธีการเล่นของพวกเขา ฉันชอบภาพ 3 มิติส่วนตัว แต่โครงการของคุณอาจเหมาะกว่าสำหรับ 2d เฉพาะคุณเท่านั้นที่จะตัดสินใจได้