คำถาม
เมื่อคุณมีเกม 2D ที่ใช้ภาพที่มีขนาดใหญ่มาก (ใหญ่กว่าฮาร์ดแวร์ของคุณสามารถรองรับได้) คุณจะทำอย่างไร อาจมีวิธีแก้ปัญหาที่น่าสนใจสำหรับปัญหานี้ซึ่งไม่เคยเกิดขึ้นกับฉันมาก่อน
ฉันกำลังทำงานกับผู้สร้างเกมผจญภัยกราฟิก ผู้ชมเป้าหมายของฉันคือผู้ที่มีประสบการณ์การพัฒนาเกม (และการเขียนโปรแกรม) เพียงเล็กน้อยหรือไม่มีเลย หากคุณทำงานกับแอปพลิเคชันเช่นนี้คุณไม่ต้องการให้มันจัดการกับปัญหาภายในแทนที่จะบอกให้คุณ "แยกภาพของคุณออก"
บริบท
เป็นที่ทราบกันดีว่าการ์ดกราฟิกกำหนดข้อ จำกัด เกี่ยวกับขนาดของพื้นผิวที่สามารถใช้ได้ ตัวอย่างเช่นเมื่อทำงานกับ XNA คุณจะถูก จำกัด ขนาดพื้นผิวสูงสุดที่ 2048 หรือ 4096 พิกเซลขึ้นอยู่กับโปรไฟล์ที่คุณเลือก
โดยทั่วไปแล้วสิ่งนี้จะไม่ก่อปัญหามากในเกม 2D เพราะส่วนใหญ่มีระดับที่สามารถสร้างจากชิ้นส่วนที่เล็กกว่า (เช่นแผ่นกระเบื้องหรือสไปรต์ที่ถูกเปลี่ยนรูป)
แต่ลองคิดถึงเกมผจญภัยกราฟิก point'nclick แบบคลาสสิค (เช่น Monkey Island) ห้องพักในเกมผจญภัยกราฟิกมักจะได้รับการออกแบบโดยรวมโดยมีส่วนที่ทำซ้ำได้น้อยหรือไม่มีเลยเหมือนกับจิตรกรที่ทำงานในแนวนอน หรืออาจเป็นเกมเช่น Final Fantasy 7 ที่ใช้ฉากหลังที่มีการแสดงผลขนาดใหญ่
ห้องเหล่านี้บางห้องมีขนาดใหญ่พอสมควรซึ่งมีความกว้างตั้งแต่สามหน้าจอขึ้นไป ตอนนี้ถ้าเราพิจารณาภูมิหลังเหล่านี้ในบริบทของเกมความละเอียดสูงที่ทันสมัยพวกเขาจะเกินขนาดพื้นผิวที่รองรับสูงสุดได้อย่างง่ายดาย
ตอนนี้ทางออกที่ชัดเจนของเรื่องนี้คือการแบ่งพื้นหลังออกเป็นส่วนย่อย ๆ ที่พอดีกับความต้องการและวาดมันเคียงข้างกัน แต่คุณ (หรือศิลปินของคุณ) จะต้องเป็นคนที่แยกพื้นผิวทั้งหมดของคุณหรือไม่
หากคุณกำลังทำงานกับ API ระดับสูงมันอาจจะไม่พร้อมที่จะรับมือกับสถานการณ์นี้และทำการแยกและประกอบพื้นผิวภายใน (ไม่ว่าจะเป็นกระบวนการก่อนอย่างเช่น Pipeline ของเนื้อหา XNA หรือรันไทม์)
แก้ไข
นี่คือสิ่งที่ฉันคิดจากมุมมองการใช้งาน XNA
เอนจิ้น 2D ของฉันต้องการฟังก์ชั่นย่อยของ Texture2D เพียงเล็กน้อยเท่านั้น ฉันสามารถลดมันลงไปที่อินเทอร์เฟซนี้ได้จริง:
public interface ITexture
{
int Height { get; }
int Width { get; }
void Draw(SpriteBatch spriteBatch, Vector2 position, Rectangle? source, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth);
}
วิธีการภายนอกเดียวที่ฉันใช้ที่อาศัย Texture2D คือ SpriteBatch.Draw () ดังนั้นฉันจึงสามารถสร้างสะพานเชื่อมระหว่างพวกเขาโดยการเพิ่มวิธีการขยาย:
public static void Draw(this SpriteBatch spriteBatch, ITexture texture, Vector2 position, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth)
{
texture.Draw(spriteBatch, position, sourceRectangle, color, rotation, origin, scale, effects, layerDepth);
}
สิ่งนี้จะช่วยให้ฉันใช้ ITexture interchangibly ทุกครั้งที่ฉันใช้ Texture2D มาก่อน
จากนั้นฉันสามารถสร้างการใช้งานสองแบบที่แตกต่างกันของ ITexture เช่น RegularTexture และ LargeTexture ที่ซึ่ง RegularTexture จะห่อ Texture2D ธรรมดา
ในทางกลับกัน LargeTexture จะเก็บรายการของ Texture2D แต่ละรายการที่ตรงกับหนึ่งในชิ้นส่วนที่แยกของภาพเต็ม ส่วนที่สำคัญที่สุดคือการเรียก Draw () บน LargeTexture ควรจะสามารถนำการแปลงทั้งหมดมาใช้และดึงชิ้นส่วนทั้งหมดราวกับว่ามันเป็นเพียงภาพเดียวที่ต่อเนื่องกัน
ในที่สุดเพื่อให้กระบวนการทั้งหมดโปร่งใสฉันจะสร้างคลาสโหลดเดอร์แบบรวมพื้นผิวที่จะทำหน้าที่เป็นวิธีการจากโรงงาน มันจะใช้เส้นทางของพื้นผิวเป็นพารามิเตอร์และส่งกลับ ITexture ซึ่งอาจเป็น RegularTexture หรือ LargeTexture ขึ้นอยู่กับขนาดภาพเกินขีด จำกัด หรือไม่ แต่ผู้ใช้ไม่จำเป็นต้องรู้ว่ามันคือใคร
overkill หรือเสียงไม่เป็นไร?