platformers 2D: ทำไมต้องทำให้ฟิสิกส์ขึ้นอยู่กับอัตราเฟรม?


12

"Super Meat Boy" เป็น platformer ที่ยากซึ่งเพิ่งออกมาสำหรับพีซีซึ่งต้องการการควบคุมที่ยอดเยี่ยมและการกระโดดพิกเซลที่สมบูรณ์แบบ รหัสฟิสิกส์ในเกมขึ้นอยู่กับอัตราเฟรมซึ่งถูกล็อคไว้ที่ 60fps นี่หมายความว่าหากคอมพิวเตอร์ของคุณไม่สามารถรันเกมได้อย่างเต็มประสิทธิภาพฟิสิกส์จะเสียสติทำให้ตัวละครของคุณทำงานช้าลงและล้มลงบนพื้น นอกจากนี้หากปิด vsync เกมจะทำงานเร็วมาก

ผู้ที่มีประสบการณ์เกี่ยวกับการเขียนโปรแกรมเกม 2D สามารถช่วยอธิบายได้หรือไม่ว่าทำไมเกมถึงเขียนรหัสด้วยวิธีนี้ การวนลูปฟิสิกส์จะทำงานในอัตราคงที่หรือไม่จะเป็นทางออกที่ดีกว่าหรือไม่ (อันที่จริงฉันคิดว่าวงฟิสิกส์ใช้สำหรับบางส่วนของเกมเนื่องจากบางเอนทิตียังคงเคลื่อนไหวได้ตามปกติโดยไม่คำนึงถึงตัวละครในทางกลับกันตัวละครของคุณจะวิ่งอย่างรวดเร็ว [fps / 60]

สิ่งที่รบกวนฉันเกี่ยวกับการใช้งานนี้คือการสูญเสียสิ่งที่เป็นนามธรรมระหว่างเอ็นจิ้นเกมและการเรนเดอร์กราฟิกซึ่งขึ้นอยู่กับสิ่งเฉพาะของระบบเช่นจอภาพการ์ดกราฟิกและ CPU หากไม่ว่าด้วยเหตุผลใดก็ตามคอมพิวเตอร์ของคุณไม่สามารถจัดการกับ vsync หรือไม่สามารถรันเกมด้วยความเร็ว 60fps ได้มันจะทำให้คุณประหลาดใจ ทำไมขั้นตอนการเรนเดอร์ในทางใด ๆ จึงมีอิทธิพลต่อการคำนวณทางฟิสิกส์? (เกมส่วนใหญ่ในปัจจุบันจะชะลอเกมหรือข้ามเฟรม) ในทางกลับกันฉันเข้าใจว่า platformers โรงเรียนเก่าใน NES และ SNES ขึ้นอยู่กับอัตราคงที่สำหรับการควบคุมและฟิสิกส์ของพวกเขา ทำไมถึงเป็นเช่นนี้และเป็นไปได้ไหมที่จะสร้าง patformer ในหลอดเลือดดำนั้นโดยไม่ต้องพึ่งพาการมีส่วนร่วม? จำเป็นต้องสูญเสียความแม่นยำหรือไม่หากคุณแยกการเรนเดอร์กราฟิกจากส่วนที่เหลือของเครื่องยนต์

ขอบคุณและขออภัยหากคำถามเกิดความสับสน


เป็นไปตามคำถามของคุณ นี่คือบทความที่ยอดเยี่ยมที่ครอบคลุมปัญหาที่คุณอธิบายอย่างชัดเจนและวิธี "ถูกต้อง" ในการจัดการการประทับเวลาและอัตราเฟรม gafferongames.com/game-physics/fix-your-timestep
num1

จริงๆแล้วมันทำให้ฉันประหลาดใจจริง ๆ ว่าพวกเขาจะทำแบบนี้ ฉันคิดว่ามันจะต้องเป็นเพราะมันถูกสร้างขึ้นสำหรับคอนโซลเป็นหลักซึ่งสามารถพึ่งพาอัตราเฟรมได้ ที่น่าผิดหวัง!
เลน

คำตอบ:


7

ทำไม?

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

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


"พวกเขาไม่รู้อะไรเลยดีกว่า" อธิบายว่าทำไมฉันถึงใช้วิธีนั้นกับ "Jack is a Fool" แต่ - ฉันอาศัยการเรียก dt อย่างหนักตั้งแต่เฟรมสุดท้ายพร้อมด้วยตรรกะทั้งหมดของฉัน แต่ - ด้วยพิกัดจุดลอยตัวมันสามารถนำไปสู่ข้อผิดพลาดบางอย่างที่แปลกใหม่และยากที่จะทำซ้ำ
lochok

4

SMB เดิมเป็นเกมคอนโซลที่ปลอดภัยที่จะคิดว่าสามารถทำงานที่ 60fps สำหรับ Xbox360 ทั้งหมด (อาจจะ 50 เกมสำหรับผู้เล่น PAL) สมมติว่าการประทับเวลาคงที่ลดความซับซ้อนของรหัสบิตที่เป็นธรรม

ในขณะที่มันง่ายต่อการปรับขนาดของสิ่งต่าง ๆ ด้วยการประทับเวลาแบบแปรผัน - 'pos + = velocity * timestep' มันค่อนข้างยุ่งยากที่จะทำอย่างถูกต้องเมื่อคุณจัดการกับความเร่งและอัตราการเปลี่ยนแปลงของความเร่งและอื่น ๆ

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

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


1

วิธีแก้ปัญหาที่ชัดเจนคือการมี 2 ลูปทำงานแบบขนาน - การเรนเดอร์ทุกๆ 1/60 ของวินาทีและลูปเกมทุกๆ 1/60 ของวินาที

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

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


2
Meat Boy ดั้งเดิมเป็นเกมแฟลช Super Meat Boy เป็นเกม C ++
Archagon

0

ฉันไม่คิดว่ามันจะขอเกมพีซี 2 มิติที่เล่นที่ 60fps อีกต่อไป แม้แต่เกม 2D ส่วนใหญ่ก็เป็นฮาร์ดแวร์ที่เร่งความเร็วในขณะนี้ดังนั้นโดยส่วนตัวแล้วฉันไม่ต้องกังวลกับความต้องการ fps

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

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


ไม่ยากที่จะเล่นที่ 60fps แต่แสดงด้วยอัตราการรีเฟรชดั้งเดิมที่ 50Hz, 70-85Hz และ 120Hz ยังพบได้ง่าย

0

เพื่อหลีกเลี่ยงพฤติกรรมแปลก ๆ ในฟิสิกส์ 2 มิติที่พวกเขากำลังใช้อยู่

สุจริตฉันสามารถเดาได้ ฉันจะลองอธิบาย:

หัวใจของเกมคือเกมหลัก ซึ่งโดยพื้นฐานแล้วมีลักษณะดังนี้:

while(gameRunning)
{
  updateGame(timestep);
  renderGame(timestep);
}

updateGame อัพเดท gameState: ตรวจสอบอินพุตของผู้เล่น, ใช้อินพุทของผู้เล่นกับโลกของเกมและทำการจำลองทางฟิสิกส์เป็นต้น

renderGame ดึงและเคลื่อนไหวเกม

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

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

วิธีการไร้เดียงสาจะเป็น (ซึ่งฉันใช้ในเกมของฉัน * ถอนหายใจ *):

position=position+speed*timestep;
speed=speed+acceleration*timestep;

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

นอกจากนั้นอาจมีปัญหาในการตรวจจับการชนหากเวลาประทับมีขนาดใหญ่เกินไป เนื่องจากไม่มีการตรวจสอบการชนกันระหว่างสอง gameUpdates วัตถุอาจผ่านอุปสรรค

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