Câu hỏi
Khi bạn có một trò chơi 2D sử dụng hình ảnh thực sự lớn (lớn hơn phần cứng của bạn có thể hỗ trợ), bạn sẽ làm gì? Có lẽ có một số giải pháp thú vị cho vấn đề này chưa từng xảy ra với tôi trước đây.
Về cơ bản tôi đang làm việc trên một loại nhà sản xuất trò chơi phiêu lưu đồ họa. Đối tượng mục tiêu của tôi là những người có ít hoặc không có kinh nghiệm phát triển trò chơi (và lập trình). Nếu bạn đang làm việc với một ứng dụng như vậy, bạn sẽ không thích nó xử lý vấn đề bên trong hơn là bảo bạn "chia nhỏ hình ảnh của bạn" chứ?
Bối cảnh
Người ta biết rằng card đồ họa áp đặt một loạt các hạn chế về kích thước của họa tiết mà họ có thể sử dụng. Chẳng hạn, khi làm việc với XNA, bạn bị giới hạn ở kích thước kết cấu tối đa là 2048 hoặc 4096 pixel tùy thuộc vào cấu hình bạn chọn.
Thông thường, điều này không gây ra nhiều vấn đề trong các trò chơi 2D vì hầu hết trong số chúng có các cấp độ có thể được xây dựng từ các mảnh nhỏ hơn (ví dụ: gạch hoặc các họa tiết biến đổi).
Nhưng hãy nghĩ về một vài trò chơi phiêu lưu đồ họa cổ điển (ví dụ Đảo Khỉ). Các phòng trong các trò chơi phiêu lưu đồ họa thường được thiết kế tổng thể, với rất ít hoặc không có phần lặp lại, giống như một họa sĩ làm việc trên một phong cảnh. Hoặc có lẽ là một trò chơi như Final Fantasy 7 sử dụng nền tảng kết xuất sẵn lớn.
Một số trong những phòng này có thể có kích thước khá lớn, thường xuyên trải rộng từ ba màn hình trở lên. Bây giờ nếu chúng ta xem xét các nền tảng này trong bối cảnh của một trò chơi độ nét cao hiện đại, chúng sẽ dễ dàng vượt quá kích thước kết cấu được hỗ trợ tối đa.
Bây giờ, giải pháp rõ ràng cho vấn đề này là chia nền thành các phần nhỏ hơn phù hợp với yêu cầu và vẽ chúng cạnh nhau. Nhưng bạn có nên (hoặc nghệ sĩ của bạn) phải là người chia tách tất cả các kết cấu của bạn?
Nếu bạn đang làm việc với API cấp cao, có lẽ không nên chuẩn bị để xử lý tình huống này và thực hiện phân tách và lắp ráp các kết cấu bên trong (như là một quy trình trước như Đường ống nội dung của XNA hoặc trong thời gian chạy)?
Biên tập
Đây là những gì tôi đã nghĩ, từ quan điểm thực hiện XNA.
Công cụ 2D của tôi chỉ yêu cầu một tập hợp con rất nhỏ của chức năng Texture2D. Tôi thực sự có thể giảm nó xuống giao diện này:
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);
}
Phương thức bên ngoài duy nhất tôi sử dụng dựa trên Texture2D là SpriteBatch.Draw () để tôi có thể tạo cầu nối giữa chúng bằng cách thêm phương thức mở rộng:
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);
}
Điều này sẽ cho phép tôi sử dụng ITexture thay thế cho nhau bất cứ khi nào tôi sử dụng Texture2D trước đó.
Sau đó, tôi có thể tạo ra hai triển khai khác nhau của ITexture, ví dụ: Chính quy và Công cụ lớn, trong đó Chính quy đơn giản sẽ bao bọc một Texture2D thông thường.
Mặt khác, LargeTexture sẽ giữ một Danh sách của Texture2D tương ứng với một trong những mảnh được tách ra của hình ảnh đầy đủ. Phần quan trọng nhất là việc gọi Draw () trên LargeTexture sẽ có thể áp dụng tất cả các phép biến đổi và vẽ tất cả các phần như thể chúng chỉ là một hình ảnh liền kề nhau.
Cuối cùng, để làm cho toàn bộ quá trình trở nên trong suốt, tôi sẽ tạo một lớp trình tải kết cấu hợp nhất sẽ hoạt động như một Phương thức xuất xưởng. Nó sẽ lấy đường dẫn của kết cấu làm tham số và trả về một ITexture có thể là một Kiểu thông thường hoặc LargeTexture tùy thuộc vào kích thước hình ảnh vượt quá giới hạn hay không. Nhưng người dùng không cần biết đó là cái gì.
Một chút quá mức hoặc nó có vẻ ổn?