"รหัสตรรกะของเกมคืออะไร"


50

ฉันใช้ C # / XNA และได้รับการบอกกล่าวสองสามครั้งเพื่อไม่ให้มิกซ์โค้ดอัปเดตกับรหัสการจับ - และฉันมั่นใจว่าฉันไม่ได้! แต่ใครก็ได้โปรดอธิบายว่า 'รหัสตรรกะ' คืออะไรกันแน่?

เท่าที่เห็นที่นี่: http://blogs.msdn.com/b/shawnhar/archive/2007/07/25/understanding-gametime.aspx

[... ] ตรวจสอบให้แน่ใจว่าคุณได้วางตรรกะของเกมทั้งหมดไว้ในวิธีการอัพเดท (ไม่ใช่ใน Draw!) และทุกอย่างจะทำงานด้วยความเร็วคงที่ดี

ฉันถามสิ่งนี้เนื่องจากความเร็วของเกมของฉันผันผวนเมื่อเทียบกับ FPS FPS ช้าเท่ากับวัตถุที่เคลื่อนไหวช้าและวีซ่าในทางกลับกัน และใช่ฉันรวมposition += speed * (float)gt.ElapsedGameTime.TotalSeconds;รหัสที่คาดไว้

นี่อาจเป็นคำถามมือใหม่ แต่ฉันต้องการให้ชัดเจนกับคำจำกัดความของเรื่องนี้


position = speed * ...TotalSecondsฉันคิดว่าคุณหมายถึง แจ้งให้ทราบก็ไม่ได้= +=หากเป็น+=เช่นเดียวกับที่คุณพิมพ์แล้วตำแหน่งของคุณจะบินออกจากหน้าจอเกือบจะทันที
DrZ214

ฉันมีรหัสที่ดูเหมือนว่า 'position + = direction * speed * ... TotalSeconds' และทำงานได้ดีมาก ฉันอาจพิมพ์ผิดบางอย่าง แต่ position = speed จะกำหนดทุกการอัปเดต วิธีของคุณอาจใช้งานได้ แต่ฉันขอให้รหัสของฉันทำงานเช่นนี้ (โปรดทราบว่าทิศทางนั้นเป็นมาตรฐาน)
Shyy Guy

ฉันคิดว่าgt.ElapsedGameTime.TotalSecondsจำนวนวินาทีที่ผ่านไปจากการเริ่มต้นโปรแกรม (เกม) หากคุณคูณความเร็วของคุณด้วยหลังจากนั้น 5 วินาทีในการเล่นความเร็วของคุณจะเร็วขึ้น 5 เท่า (ยกเว้นกรณีพิเศษที่ตั้งค่าความเร็วเป็น 0) ไม่แน่ใจว่าคุณมีสิ่งใดที่จะทำให้เรื่องนั้นเป็นจริง แต่ฉันก็รู้สึกทึ่ง
DrZ214

1
อ๊ะมันเป็นตั้งแต่การอัพเดทครั้งล่าสุด gamedev.stackexchange.com/questions/67968/…
Shyy Guy

2
ที่น่าสนใจฉันจะไม่คาดเดาว่า ไม่จำเป็นต้องมีสิ่งใด ๆ ภายในไม่กี่วินาทีเพราะฉันใช้ตัวแปรของตัวเองที่เรียกiiiว่าฉันเพิ่มการอัพเดททุกครั้งด้วยตนเองเพราะฉันไม่ต้องการภายในไม่กี่วินาทีฉันต้องการขั้นตอนหรือเฟรม ฉันจะเห็นว่าวิธีการของคุณเป็นวิธีที่ถูกต้องของสิ่งที่อ่อนนุ่มการเข้ารหัส
DrZ214

คำตอบ:


102

มันเปลี่ยนสถานะของโลกเกมของคุณหรือไม่? มันเป็นรหัสตรรกะ

มันแสดงสถานะของโลกของเกมหรือไม่? มันเป็นรหัสการแสดงผล


ฉันจะดูรหัสของฉันเพื่อให้แน่ใจ 100% คำอธิบายที่ดีขอบคุณ
Guy ขี้อาย

38
มันจัดการกับอินพุตหรือไม่ รหัสควบคุม แยกการควบคุมออกจากตรรกะเพื่อให้คุณสามารถใช้ตรรกะเดียวกันกับการควบคุมประเภทต่าง ๆ ได้ เช่น FPSInputController + CharacterMotor กับ AIInputController + CharacterMotor เทียบกับ NetworkInputController (เช่นผู้เล่นอื่นในอินสแตนซ์ของผู้เล่นหลายคน) + CharacterMotor มอเตอร์ (รหัสลอจิก) ไม่สนใจว่าจะได้รับคำแนะนำอย่างไรเฉพาะเมื่อมีการให้ (การแยกประเภทนี้ช่วยให้เปลี่ยนจากผู้เล่นเป็นบอท AI ได้ง่าย (คิดว่า Left 4 Dead และ idle player) และด้านหลัง เหนือสิ่งอื่นใด).
Draco18s

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

การทำให้พวกเขาแตกต่างจะช่วยให้คุณจัดการความต้องการของคุณเมื่อพวกเขาเริ่มเป็นแหล่งของความเครียด
Cort Ammon

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

24

การแยกของคุณถูกต้องหาก:

  • การเรียก Draw () หลายครั้งติดต่อกันโดยไม่ต้องทำการสลับไปยัง Update () หลายครั้งจะไม่ส่งผลให้เกิดการเปลี่ยนแปลงใด ๆ ระหว่างการโทร
  • Calling Update () หลายครั้งติดต่อกันโดยไม่ต้องสลับเป็น Draw () เป็นเหมือนการเล่นเกมโดยที่หน้าจอดับลง: ทุกอย่างเคลื่อนที่ไปอย่างสมบูรณ์แบบและต่อเนื่องคุณแค่มองไม่เห็น

5
เขียนอย่างถูกต้องDraw()อาจวาดภาพที่แตกต่างกันเมื่อเวลาผ่านไป ตัวอย่างเช่นเฟรมของภาพเคลื่อนไหวสไปรต์อาจมีการเปลี่ยนแปลง นอกจากนี้วัตถุยังสามารถเดินหน้าต่อไปได้หากรหัสการแสดงผลใช้กลอุบายทั่วไปและเพิ่มvelocity * time since last update / period of updateไปยังตำแหน่งที่มองเห็นของวัตถุ (ในขณะที่ตำแหน่งจริงยังคงไม่เปลี่ยนแปลง)
HolyBlackCat

2
iffความหมายถ้าและเพียงอย่างเดียวถ้า?
BalinKingOfMoria

3
@HolyBlackCat: นั่นเป็นเหตุผล ถ้าฉันต้องการหยุดกราฟิกชั่วคราว เกิดอะไรขึ้นถ้าเฟรมของภาพเคลื่อนไหวมีผลกับเกม (ภาพเคลื่อนไหวการโจมตีที่สอดคล้องกับ hitboxes เป็นต้น) ภาพการแก้ไขยังคงแสดงให้เห็นว่า "เวลา" (ในขณะเวลาเดลต้าเกม) จะผ่าน แต่ถ้ามีเวลาจะผ่านและคุณไม่ได้Updateไอเอ็นจีแล้วสิ่งอื่น ๆ ที่จะได้รับออกจากซิงค์? อินพุตของผู้เล่นถูกพลาดกิจกรรมเครือข่ายที่ไม่ได้รับการประมวลผล ฯลฯ ? เกมนี้ควรถูกขับออกจากนาฬิกาเดียวโดยมี "เครื่องหมาย" คงที่สำหรับตรรกะของเกมหรือฟิสิกส์ที่ได้มาจากนาฬิกานั้นและสถานะกราฟิกที่ได้รับก็มาจากนาฬิกาเดียวกันนั้น
Sean Middleditch

@ SeanMiddleditch ฉันเห็นด้วยคุณเกือบจะสามารถเขียนDraw()ด้วยวิธีดังกล่าวได้เสมอดังนั้นมันจึงวาดรูปเดียวกันเมื่อเรียกหลายครั้งติดต่อกัน ควรทำอย่างนั้นถ้าเป็นไปได้ แต่มีหลายกรณีที่คุณไม่รู้ว่าDraw()จะเรียกความถี่อย่างไร ตัวอย่างเช่นหากคุณต้องการการสนับสนุนอย่างเต็มที่ (120 FPS จริง) สำหรับจอภาพ 120hz ใหม่และคุณเปิด vsync What if I want to pause graphics?จากนั้นคุณผ่าน 0 Draw()แทนเวลาเดลต้าที่เกิดขึ้นจริงกับ
HolyBlackCat

2
@HolyBlackCat: ไม่มีอะไรที่ฉันได้รับที่จะขัดขวางการใช้การแสดงผล 120hz ฉันไม่ได้แนะนำอัตราการวาดคงที่อย่างแน่นอน นั่นเป็นเพียงชำนาญ ควรมีหนึ่งนาฬิกาเกมทั่วโลกที่มีการวัดเดลต้าในแง่ของเฟรมการเรนเดอร์ที่ป้อนเข้าสู่ค่าการสะสมสำหรับเห็บตรรกะเกมอัตราคงที่ นาฬิกาทั่วโลกนั้นไดรฟ์กราฟิกรวมถึงการแก้ไข 0คุณสามารถหยุดกราฟิกโดยการตั้งค่าขนาดนาฬิกาเพื่อ คุณสามารถมีนาฬิกาแบบลำดับชั้นได้เช่น UI ยังคงทำงานและเคลื่อนไหวในขณะที่การแก้ไขตัวละครหยุดเช่นกันได้อย่างง่ายดายมาก
Sean Middleditch

7

จุดนี่คือการแยกสิ่งต่าง ๆ ของแบบจำลองที่ไม่ใช่แบบจำลอง

ลอจิกเกมเป็นรูปแบบตามที่อ้างถึงใน

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

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

คล้ายกันไปสำหรับตรรกะของเกม

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

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

ตรรกะของเกมเป็นสิ่งที่ไม่เคยเปลี่ยนแปลงไม่ว่าจะอยู่ในรูปแบบใด

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