เป็นเธรดแยกต่างหากสำหรับการบังคับเกมลูปสำหรับเกมแบบง่ายหรือไม่?


10

ฉันยังใหม่ต่อการพัฒนาเกม เพื่อเรียนรู้ฉันกำลังสร้างเกมนี้บนแพลตฟอร์ม Android คุณสามารถดูวิดีโอการเล่นเกมได้ที่ลิงค์ด้านบน มันเป็นเกมที่ง่าย

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



ไม่แน่ใจว่านี่เป็นสิ่งซ้ำซ้อนเนื่องจากเป็นเรื่องเกี่ยวกับ Android มีข้อควรพิจารณาอื่น ๆ เกี่ยวกับการทำเกลียวในแพลตฟอร์มบน Java ที่แตกต่างจากคำถามนั้น
Sean Middleditch

คำตอบ:


8

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

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

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

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


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

ดังนั้นคุณไม่ได้ถามว่าต้องการลูปหรือไม่? ข้อกังวลหลักของคุณคือถ้ามันต้องอยู่ในเธรดแยกต่างหากใช่ไหม?
AturSams

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

1
ไม่ไม่จำเป็น ตราบใดที่คุณต้องห่วงแล้วมีไม่จำเป็นต้องสร้างวงที่สอง

@ Jin คุณควรเปลี่ยนชื่อและวิธีเขียนคำถามของคุณแล้ว
vallentin

5

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

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


ตอบคำถามต้นฉบับ "จำเป็นต้องมีการวนซ้ำ"

ไม่แต่ตัวเลือกมีความซับซ้อนมากขึ้นยากที่จะนำไปใช้และไม่ค่อยได้ใช้

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

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

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


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

2

ตอบคำถามจริง (ลูปของเกมจำเป็นต้องอยู่ในเธรดแยกต่างหาก):

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

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

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

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

เฟรมเวิร์กบางตัวสนับสนุน / ต้องการให้คุณใช้งานและระบบ / เหตุการณ์ขัดจังหวะเช่นเดียวกับ ActionScript3.0 ในกรณีดังกล่าวรหัสการวนซ้ำมักจะไปที่OnEnterFrameเหตุการณ์หรือสิ่งที่คล้ายกันที่เกิดขึ้น 20 - 60 หรือ 120 ครั้งต่อวินาที


ตอบคำถามเดิม (ฉันต้องมีวนรอบหลัก):

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

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

ดังนั้นเพื่อตอบคำถามก่อนหน้านี้คุณต้องการวนซ้ำหรือไม่? ใช่คุณทำ


1
เท่าที่ฉันรู้กรอบตามเหตุการณ์เช่น AS3 ยังคงมีการวนรอบเกมที่ทำงานภายใต้ ฉันกำลังพูดถึงการขัดจังหวะในระดับที่ต่ำกว่าไม่ใช่กรอบที่ใช้ระบบเหตุการณ์
MichaelHouse

อืม .. ฉันไม่คิดว่าผู้คนมักใช้การขัดจังหวะระดับต่ำในเกม AFAIK ส่วนใหญ่จะใช้โดย CPU เพื่อตรวจสอบการทำงานของ IO ฉันคิดว่า abstraction ระดับสูงกว่าเป็นแบบฝึกการออกแบบที่คุณตอบสนองต่อการป้อนข้อมูลของผู้ใช้หรือกิจกรรมฮาร์ดแวร์ (โดยไม่ต้องโพล) แทนที่จะเรียกใช้หลายคำสั่งทุกเฟรมแล้วบอก HW เพื่อให้ได้ผลลัพธ์
AturSams

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

ฉันเห็นด้วยกับ @ Byte56 มันเดือดลงไปเป็นลูปเว้นแต่ว่าเรากำลังพูดถึงเหตุการณ์ระดับเคอร์เนลที่ใช้การขัดจังหวะ IO
concept3d

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

0

เพียงเพิ่มคำตอบของคนอื่นที่นี่สิ่งที่ไม่มีใครได้กล่าวไว้อย่างชัดเจน: หากคุณเสี่ยงต่อการวนลูปเกมของคุณในเธรดที่สองและมันไม่ตอบสนองคุณเสี่ยงต่อการยกเลิกระบบปฏิบัติการของคุณ นั่นเป็นสาเหตุที่แนะนำให้ใช้เธรดแยกต่างหาก ดังนั้น (ตัวอย่าง) NDK ของnative_app_glue.c/ .hวางไข่ด้ายแยกต่างหากสำหรับวงของคุณ

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