Tôi hiện đang phát triển một trò chơi roguelike 3D sẽ diễn ra trong một thế giới rất rộng lớn. Thế giới được tạo ra bởi thuật toán thủ tục được cung cấp bởi tập lệnh bên ngoài trong thời gian chạy. Để tăng tốc độ kết xuất và tối thiểu hóa các yêu cầu về bộ nhớ, tôi đang chia thế giới thành các khu vực. Một vùng là một hình chữ nhật 2D có kích thước tối đa 1024 x 1024 (không cần phải là một hình vuông), chứa new
mảng được phân bổ động (thông qua một ) của Tile
's. Tile
được định nghĩa là càng nhỏ càng tốt, để tối thiểu hóa việc sử dụng bộ nhớ. Chỉ các vùng hiển thị trên màn hình hoặc trong vùng lân cận ngay lập tức nằm trong bộ nhớ, phần còn lại được tải từ tệp đĩa cứng theo nhu cầu.
Vấn đề tôi gặp phải là trình tạo bản đồ không cần biết về bố cục vùng logic, do đó, nó có thể tạo ra loại bản đồ này (đặc biệt đối với các cấp Z cao hơn, như lofts trong thành phố):
Đây sẽ là quá nhiều lãng phí bộ nhớ để gửi nó trong 1024 x 1024, vì vậy, tốt hơn là đặt nó vào các phần nhỏ hơn như thế này:
Vì vậy, cuối cùng câu hỏi: làm thế nào tôi có thể chuyển đổi dữ liệu được cung cấp bởi tập lệnh trình tạo thế giới thành cấu trúc thế giới thực trong bộ nhớ?
Những gì tôi đã nghĩ về cho đến nay:
- Script có một phương thức
SetTile(x, y, tileType)
và thế giới sẽ tự động tính toán lại sau mỗi giả sử 100 ô, vì vậy các vùng được đặt hiệu quả nhất có thể. Điều này sẽ yêu cầu RẤT NHIỀU sao chép vùng, di chuyển, thay đổi kích thước, v.v. - đó là một hoạt động rất chậm, nhưng nó sẽ giữ bố cục thế giới theo thứ tự hợp lý, vì vậy, ví dụ sẽ dễ thực hiện các phương thức nhưGetTile(x, y)
trong tập lệnh - Script có một phương thức
SetTile(x, y, tileType)
tạm thời chỉ lưu trữ một Ngói vào std :: vector và sau khi mọi thứ hoàn thành, thế giới sẽ chạy một lượt thứ hai tính toán các vùng. Cách này nhanh hơn, nhưng có một nhược điểm - vì Ngói được đặt không theo thứ tự cụ thể, nên thực sự khó cóGetTile(x, y)
phương pháp trong tập lệnh. Có lẽ có một giải pháp cho nhược điểm đó, tôi chỉ không có bất kỳ ý tưởng nào -std::map
là quá chậm để được sử dụng ở đây. - Nếu không thể thực hiện tắt màn hình, có thể giải pháp sẽ là hiển thị các vùng thành tập lệnh và được tạo rõ ràng (ý tôi là đưa vào
CreateZone()
chức năng API tập lệnh và tương tự) - Tôi không muốn điều này, vì tập lệnh sẽ được hiển thị cho người dùng cuối và Tôi muốn làm cho họ mạnh mẽ nhất có thể. - Có lẽ có giải pháp nào khác? Có lẽ tôi có thể tổ chức thế hệ theo một cách khác (tôi vẫn cần các tập lệnh, nhưng nó có thể là một tập lệnh chỉ tạo ra một phần của thế giới và sau đó kết nối)?
Những điều bổ sung tôi vừa nghĩ ra: toàn bộ thế giới có thể quá lớn để có thể đưa vào bộ nhớ cùng một lúc. Vì vậy, nó xoay vấn đề hơn nữa - tôi phải chia phần thế hệ (theo kịch bản) thành các giai đoạn. Bất kỳ đề xuất?
Về công nghệ: Tôi đang sử dụng C ++ 03 'mà không có Boost và AngelScript làm ngôn ngữ kịch bản