คำถามเกี่ยวกับสถาปัตยกรรมเกมด้วย XNA


12

ในที่สุดฉันก็เลยได้เล่นกับ XNA และเล่นด้วยการทำเกม 2D (ฉันมีทรัพย์สินทางศิลปะมากมายจากเพื่อนที่พัฒนาบน iOS)

ดูเหมือนจะเป็นเรื่องง่ายมากที่จะทำและออกมาจากกล่อง แต่ฉันถูกทิ้งไว้กับสิ่งต่าง ๆ ตั้งแต่วรรณกรรมส่วนใหญ่ (หนังสือที่ฉันซื้อมาเป็นตัวอย่าง) ไม่สนใจ 2D มากนัก

ฉันขอขอบคุณการชี้แจงหรือชี้ไปที่ข้อมูลเพิ่มเติมเกี่ยวกับภารกิจต่อไปนี้:

  1. จุดบริการเกมคืออะไร ฉันเข้าใจถึงสำนวนทั้งหมดของการลงทะเบียนวัตถุเป็นบริการเพื่อให้ GameComponent อื่น ๆ สามารถคว้ามันได้อย่างไรสิ่งนี้ทำให้เอาชนะได้ง่ายเพียงแค่ทำให้เป็นสาธารณะหรือคงที่? ตัวอย่างเช่นหนังสือของฉันแนะนำให้ลงทะเบียนวัตถุ SpriteBatch ในคลาส Game.cs ฉันไม่แน่ใจว่าสิ่งนี้จะดีกว่าที่จะทำให้เป็นแบบสาธารณะ / คงที่เนื่องจากควรมีเพียงหนึ่งตัวอย่างของเกม anyways (ซิงเกิลตัน)?

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

  3. ฉันสังเกตเห็นว่า Initialize เรียกก่อน ContentLoad () ฉันพบว่ามันน่ารำคาญเนื่องจากใน Initialize ของฉันเป็นที่ที่ฉันต้องการสร้างเอนทิตีของฉัน (เช่น Sprite, Player ฯลฯ .. ) แต่ฉันไม่สามารถให้พวกมันโหลดได้ SpriteSheets หรือ Textures ตั้งแต่การโทรเพื่อโหลดมันยังไม่เกิดขึ้น ฉันกำลังเริ่มต้นอย่างไม่ถูกต้องหรือผู้คนเพิ่งกำหนดพื้นผิวเพิ่มเติมใน ContentLoad หรือไม่

สิ่งเหล่านั้นดูเหมือนจะเป็น " WTF " ที่ใหญ่ที่สุดของฉันที่ไม่เข้าใจจริงๆ

คำตอบ:


11

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

ในการตอบคำถามข้อหนึ่งฉันจะแนะนำคุณให้ตอบคำถาม "ทำไมต้องใช้บริการ" . คำตอบสั้น ๆ ว่าบริการเป็นวิธีที่ดีที่จะหลีกเลี่ยงการมีเพศสัมพันธ์ (เวอร์ชันพึ่งพาการขยาย) ประเด็นที่ว่าคุณจะไม่เคยเผชิญหน้ากันในเกมที่ตนเองมี เวลาส่วนใหญ่นั้นง่ายกว่าที่จะเพียงแค่สมัครสมาชิกpublic(และอาจเป็นไปได้staticถ้าคุณรีบ) และกังวลเกี่ยวกับปัญหาที่น่าสนใจมากขึ้น

ในการตอบคำถามที่สองของคุณฉันจะแนะนำคุณให้ตอบคำถาม "อะไรคือข้อเสียของการใช้ DrawableGameComponent สำหรับทุก ๆ อินสแตนซ์ของวัตถุเกม" เช่นเดียวกับฉันคิดเกี่ยวกับสถาปัตยกรรมเกม คำตอบสั้น ๆ คือ: ไม่มีประโยชน์ที่จะใช้GameComponentover เพียงแค่สร้างชั้นเรียนของคุณเองและวิธีการโทรเช่นDrawและUpdateตัวคุณเอง หากGameComponentตรงกับสถาปัตยกรรมที่คุณต้องการทุกอย่างใช้มัน แต่ก็ไม่ได้

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

สุดท้ายคำตอบสำหรับคำถามที่สามของคุณจะค่อนข้างง่าย: LoadContentเพียงแค่สร้างหน่วยงานในเกมของคุณ Initializeไม่มีอะไรพิเศษโดยเฉพาะอย่างยิ่งเกี่ยวกับการเป็น

มันคุ้มค่าที่ชี้ให้เห็นว่าทั้งMicrosoft.Xna.Framework.Gameการชุมนุมเป็นตัวเลือก มันเป็นจุดเริ่มต้นที่มีประโยชน์อย่างยิ่ง - แต่ไม่ควรถูกมองว่าเป็น "ทางที่ถูกต้อง" ในการทำสิ่งต่าง ๆ


วิธีที่น่าสนใจมากที่จะเห็นมัน สมจริงมากขึ้นและลงสู่พื้นดินมากกว่าคำตอบของฉัน สมควร +1 ดีครับ
Jesse Emond

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

@Setheron: คุณควรสร้างคำถามใหม่จริง ๆ - เนื่องจากคำถามนี้ไม่เกี่ยวข้องกับคำถามเดิม ฉันจะยกเลิกการแก้ไขที่คุณทำกับคำถามนี้ ต้นกำเนิดสำหรับSpriteBatch.Drawถูกระบุในพิกัด texture-pixel สัมพันธ์กับด้านบนซ้ายของพื้นผิว (หรือสี่เหลี่ยมผืนผ้าแหล่งถ้าคุณใช้หนึ่ง)
Andrew Russell

1
@ แอนดรูว์: ฉันเพิ่งปรับปรุงเกมของฉันใหม่เพื่อให้เป็นไปตามบริการทั้งหมดแทนที่จะเป็นpublic/ staticคุณสมบัติ ทำไม? การตรวจสอบได้ มันใกล้จะเป็นไปไม่ได้ที่จะเปลี่ยนสิ่งต่าง ๆ ด้วยวิธีการของอสังหาริมทรัพย์ในขณะที่มันไม่สำคัญถ้าทุกอย่างเริ่มต้นด้วยสิ่งIServiceProviderที่สามารถอัดแน่นไปด้วยทุกสิ่งที่ชั้นเรียนต้องการโดยวิธีการทดสอบของคุณ นอกจากนี้ยังหลีกเลี่ยงความจำเป็นในการสร้างอินสแตนซ์ของGameวัตถุในการทดสอบของคุณซึ่งทำให้ยุ่งเหยิงอย่างรวดเร็ว
Matthew Scharley

นอกจากนี้ฉันยังมีคุณสมบัติสาธารณะมากมายบนGameวัตถุ พวกเขาเพิ่งจะสามารถเข้าถึงได้ผ่านอินเทอร์เฟซที่ถูกผลักเข้ามาGame.Servicesซึ่งจะถูกส่งต่อไปยังทุกสิ่งเพื่อรับสิ่งที่ต้องการ
Matthew Scharley

3

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

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

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

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

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