แยกฟิสิกส์และตรรกะเกมออกจากรหัส UI


12

ฉันกำลังทำงานในเกมตัวต่อที่ง่าย

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

ฉันแบ่งรหัสออกเป็นสองส่วน: ตรรกะของเกมและ UI อย่างที่ฉันทำกับเกมปริศนามากมาย:

  • ตรรกะของเกมรับผิดชอบกฎทั่วไปของเกม (เช่นระบบกฎอย่างเป็นทางการในหมากรุก)
  • UI แสดงพื้นที่เกมและชิ้นส่วน (เช่นกระดานหมากรุกและชิ้นส่วน) และรับผิดชอบภาพเคลื่อนไหว (เช่นการเคลื่อนไหวของชิ้นส่วนหมากรุก)

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

UI ใช้กริดนี้และวาดโดยการแปลงขนาดโลจิคัลเป็นขนาดพิกเซล (นั่นคือคูณด้วยค่าคงที่) อย่างไรก็ตามเนื่องจากเกมแทบจะไม่ได้มีตรรกะของเกมเลยเลเยอร์ตรรกะในเกมของฉัน [1] จึงไม่ต้องทำอะไรมากมายนอกจากการตรวจจับการชน นี่คือวิธีการทำงาน:

  1. ผู้เล่นเริ่มลากชิ้นส่วน
  2. UI ถามตรรกะของเกมสำหรับพื้นที่การเคลื่อนไหวทางกฎหมายของชิ้นส่วนนั้นและให้ผู้เล่นลากมันภายในพื้นที่นั้น
  3. ผู้เล่นปล่อยชิ้นส่วนไป
  4. UI จัดเรียงส่วนเข้ากับกริด (เพื่อให้อยู่ในตำแหน่งตรรกะที่ถูกต้อง)
  5. UI บอกตรรกะของเกมถึงตำแหน่งโลจิคัลใหม่ (ผ่านวิธีการเปลี่ยนแปลงซึ่งฉันควรหลีกเลี่ยง)

ฉันไม่ค่อยมีความสุขกับสิ่งนั้น:

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

ฉันคิดว่าสิ่งที่ดีที่สุดที่จะทำคือกำจัดชั้นตรรกะของเกมและใช้เลเยอร์ฟิสิกส์แทน ฉันมีคำถามสองสามข้อเกี่ยวกับเรื่องนี้:

  1. เลเยอร์ฟิสิกส์เป็นเรื่องธรรมดาหรือเป็นเรื่องธรรมดามากกว่าที่จะให้เลเยอร์เกมลอจิกทำเช่นนี้?
  2. การสแนปไปยังกริดและรหัสการลากชิ้นส่วนจะเป็นของ UI หรือเลเยอร์ฟิสิกส์หรือไม่
  3. เลเยอร์ฟิสิกส์แบบนี้จะทำงานกับขนาดพิกเซลหรือหน่วยทางลอจิคัลบางประเภทเช่นเลเยอร์ตรรกะเกมของฉันหรือไม่
  4. ฉันเคยเห็นการตรวจจับการชนกันของเหตุการณ์ในฐานรหัสของเกมหนึ่งครั้งนั่นคือผู้เล่นจะลากชิ้นส่วน UI จะแสดงผลอย่างเชื่อฟังและแจ้งให้ทราบถึงระบบฟิสิกส์และระบบฟิสิกส์จะเรียกวิธี onCollision () บนชิ้นงานเมื่อตรวจพบการชน เป็นเรื่องธรรมดามากขึ้น? วิธีนี้หรือขอพื้นที่เคลื่อนไหวทางกฎหมายก่อน?

[1] เลเยอร์อาจไม่ใช่คำที่ถูกต้องสำหรับสิ่งที่ฉันหมายถึง แต่ระบบย่อยฟังดูไม่น่าเชื่อและคลาสก็เข้าใจผิดเพราะแต่ละชั้นอาจประกอบด้วยหลายชั้น


คำตอบของฉันช่วยได้ต้องการข้อมูลเพิ่มเติมหรือไม่?
Will Marcouiller

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

คำตอบ:


3

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

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

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

ดังนั้นนี่คือความคิดของฉันในหัวข้อ - ฉันหวังว่ามันจะช่วย:

  1. เลเยอร์ GUI: เลเยอร์นี้จะมีวิธีการเฉพาะในการแสดงชิ้นส่วนบนกระดานเกมเพื่อให้เกิดการโต้ตอบระหว่างเกมกับผู้เล่น;
  2. เลเยอร์ตัวควบคุมเกม: รับผิดชอบอินพุตของผู้เล่น นั่นคือเลเยอร์ที่ควรบอกให้ชิ้นส่วนเคลื่อนไหวในทิศทางที่แตกต่างกันและถามกระดานเกมว่าจะมีการชนกันตามการเคลื่อนไหวหรือไม่
  3. เลเยอร์ธุรกิจ: เลเยอร์นี้จะมีชั้นธุรกิจทั้งหมดของคุณนั่นคือชิ้นส่วนของเกมของคุณและวัตถุกระดานเกมที่มีชิ้นส่วนปริศนา

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

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

ขอบคุณที่อ่าน! =)


2
ซึ่งฟังดูคล้ายกับ Model View Controller มาก
tenpn

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

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

เฮ้ฉัน blogged เกี่ยวกับ "MVC" ในการพัฒนาเกมไม่กี่เดือนที่ผ่านมา ใช่มันเป็นแนวคิดเกตเวย์ที่ดีสำหรับผู้ที่ไม่ได้ฝึกหัดกับการพัฒนาเกม: codecube.net/2010/08/xna-for-the-everyday-developer
Joel Martinez

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