Cách xử lý một Thế giới khối như Minecraft


9

Tôi muốn viết một game đơn giản với một thế giới khối như trong Minecraft. Câu hỏi lý thuyết của tôi là cách tốt nhất để xử lý thông tin khối này trong khi chơi. Ý tưởng đầu tiên của tôi là một mảng lớn nhưng điều này sẽ khiến tôi hết bộ nhớ. Có lẽ tôi phải chỉ tải các khối gần người chơi.

Làm cách nào tôi có thể xử lý việc tải thông tin khối cần thiết từ một tệp và chỉ giữ những thông tin cần thiết trong bộ nhớ?


2
Minecraft tải thế giới thành những khối khá lớn gọi là Chunks, không phải tất cả cùng một lúc. Tôi không chắc chắn về các chi tiết chính xác. Nguồn Minecraft khá dễ nắm bắt nếu bạn muốn xem thử nó đã biến mất như thế nào.
ratbum

Hãy xem wiki minecraft
tom van green

Tôi đã biết về chunk trong Minecraft, nhưng dù sao cũng cảm ơn.
danijar

Đây là một câu hỏi phức tạp không phù hợp với phạm vi của blog này.

Câu trả lời:


9

Có một vài cách khác nhau để lưu trữ dữ liệu cho một trò chơi với các khối như Minecraft.

Cách tôi tin Minecraft làm điều đó là phá vỡ thế giới trong Chunks 16x16x256. Các đoạn xung quanh người chơi được tải vào bộ nhớ khi người chơi bắt đầu trò chơi, sau đó một luồng nền sẽ tải nhiều hơn khi bạn đi bộ xung quanh. Đây là video cho thấy nó: http://www.youtube.com/watch?v=oR_ZdJH9eho .

Một cách khác để làm điều đó là phá vỡ thế giới thành một Octree. Michael Goodfellow đã viết một blog về việc triển khai một thế giới khối với cấu trúc dữ liệu này: http://www.sea-of-meme.com/LetsCode1/LetsCode1.html . Octree là tốt bởi vì nó cung cấp cho bạn một số nén được tích hợp, nhưng có lẽ sẽ khó hơn một chút để làm việc với một Array.

Về việc giữ "những thứ cần thiết duy nhất trong bộ nhớ?" Điều này khó hơn một chút vì bạn phải hỏi "cần thiết" là gì. Nếu bạn có các NPC sống ở một nơi khác trên thế giới có AI tương tác với môi trường thì bạn "cần" rất nhiều thế giới để có trong bộ nhớ. Dữ liệu thế giới của Voxel có thể nhận được rất lớn rất nhanh, vì vậy tốt nhất bạn nên cố gắng giữ số lượng ít nhất có thể trong bộ nhớ. (IE, chỉ có NPC gần trình phát).

Công cụ đồ họa sẽ "cần" mọi khối không bị bao quanh hoàn toàn bởi các khối không trong suốt khác. Cách thông thường để kết xuất thế giới là xây dựng một lưới duy nhất chứa các đỉnh cho mọi khối có thể nhìn thấy. Việc vẽ này nhanh hơn nhiều vì bạn chỉ thực hiện 1 cuộc gọi đến các phương thức vẽ cho 65.536 khối (trong khối kích thước Minecraft). Vì công cụ đồ họa sẽ cần xây dựng lưới này, nên nó thường cần biết tất cả các hình khối trong một khối. Lưu ý rằng đây là lý do tại sao khi bạn nhìn xuyên qua sàn trong Minecraft, rất nhiều thế giới là vô hình. Điều này là do mọi khối được bao quanh trên tất cả sáu mặt đều bị bỏ qua. Tôi tin rằng Minecraft cũng giảm số lượng đỉnh bằng cách kết hợp các mặt ngang của cùng loại kết cấu vào một hộp với kết cấu lặp lại.

Lời khuyên của tôi sẽ là đi với các khối 16x16x256. Lưu trữ chúng trong một mảng vì bạn sẽ cần lặp lại và chỉnh sửa nhanh do xây dựng logic lưới và trò chơi (phát hiện va chạm, thêm / xóa khối, ect). Sau đó tải càng nhiều khối trong một vòng tròn xung quanh người chơi càng tốt. Quy mô số lượng khối lên hoặc xuống cho máy tính tốt hơn hoặc xấu hơn.

Việc tải Chunks sẽ là một thành công lớn về hiệu suất, vì vậy hãy đặt nó trong một chuỗi chạy theo thời gian. Làm cho nó để bạn hoàn toàn có thể tải 3 Chun mới trong thời gian người chơi phải đi bộ từ đầu này sang đầu kia.


Cảm ơn bạn! Không có gì về AI vì tôi đang viết một khách hàng cho MMO. Tính toán NPC được thực hiện bởi máy chủ. Một bổ sung: Không phải "mọi khối không hoàn toàn bị bao quanh bởi các khối không trong suốt khác" là cần thiết cho công cụ đồ họa. Nếu có hang, người chơi không thể thấy chúng không quan trọng. ;-)
danijar

2
Về các hang động mà người chơi không thể nhìn thấy ... Tôi nghĩ rằng nó sử dụng ít hiệu suất hơn để chỉ vẽ các hang động hơn là để xác định xem hang có bị chặn hoàn toàn không. Và nếu bạn không vẽ các hang động thì nếu bạn loại bỏ một khối, bạn có khả năng phải tạo lại lưới cho nhiều khối thay vì chỉ một khối. Thật tuyệt khi tìm cách loại trừ các hang động, tôi chỉ không thể nghĩ ra một cách để làm điều đó một cách hiệu quả: D.
Thomas Marnell

3

Tôi có thể không có cách tốt nhất để giải thích nó nhưng tôi sẽ thử.

Tôi nghĩ cách tốt nhất để hiểu làm thế nào để nó hiệu quả hơn là hiểu Voxels. Minecraft dựa trên voxel, nó chỉ sử dụng các hình khối thay vì hình cầu, v.v.

Về cơ bản, voxel là hình dạng 3D có thể có âm lượng thay đổi linh hoạt và khi âm lượng thay đổi, hình dạng cũng vậy. Một Chunk là một bộ X của X by X của voxels. Vì vậy, ví dụ, bạn có thể có một đoạn mã có 16x16x16 voxels và sau đó bạn có thể có số lượng khối X. Bạn sẽ có một khoảng cách được đặt, rằng nếu người chơi ở xa N hơn bất kỳ khối nào, đừng đưa chúng vào tính toán của bạn. Điều này tương tự như cắt khoảng cách nhưng cũng cần phải áp dụng cho từng đoạn. Bằng cách này, bạn có thể có nó để bạn luôn có thể có người chơi của mình ở trung tâm Chunk of a, giả sử, bộ 3x3 của Chunks.

Vì vậy, những gì bạn sẽ có là một lớp để xử lý các Voxels riêng lẻ. Chúng tôi sẽ gọi nó là Voxel_cl. Và sau đó, bạn sẽ có một lớp để xử lý khối voxels, được gọi là Chunk_cl. Và sau đó, bạn sẽ có một số lớp thế giới tạo ra tất cả các khối sẽ tạo ra các voxels, được gọi là World_cl.

Vì vậy, bây giờ thay vì một mảng lớn mọi thứ, bạn sẽ có một mảng 9 Chunks bất cứ lúc nào và trong lớp chunk, bạn sẽ có một mảng 4096 voxels.

Xin lưu ý rằng đây là một lời giải thích khá đơn giản. Tôi hiện đang làm việc trên một cái gì đó bằng cách sử dụng voxels vì vậy tôi nghĩ rằng tôi sẽ ném vào đầu vào của mình = -)

Để biết thêm thông tin về voxels, hãy kiểm tra http://en.wikipedia.org/wiki/Marching_cubes


3
Marching Cubes là về trực quan hóa voxels. Và Minecraft thậm chí không sử dụng nó; nó chỉ vẽ các hình khối, đó chính xác là những gì Marching Cubes không làm.
Nicol Bolas

Cảm ơn lời giải thích của bạn! Tôi chưa bao giờ nghe nói về Voxels trước đây và nó có vẻ rất quan trọng đối với dự án của tôi. Nhưng tôi có một câu hỏi còn lại bây giờ.
danijar

Tôi hiểu việc tạo ra một mảng các khối gần trong đó mỗi phần tử chứa một mảng các voxels của đoạn này. Nhưng sau đó tôi cần xử lý thay đổi mảng chunk khi người chơi di chuyển trên thế giới. Tôi có phải đọc các đoạn cần thiết từ tệp lưu không? Hoặc có một cách tốt để giữ chúng trong bộ nhớ?
danijar

2
@danijar Chỉ cần một số câu đố, pixel là viết tắt của "phần tử hình ảnh", voxel được hình thành theo cách tương tự từ "phần tử âm lượng". Không phải là nó quan trọng đối với bất cứ điều gì, nhưng vì bạn đã không nghe thấy thuật ngữ voxel trước khi tôi nghĩ nó có thể khiến bạn quan tâm.
Daniel Carlsson

1

Bạn có thể cố gắng chỉ làm cho các bề mặt hiển thị được hiển thị, máy tính xử lý khối dữ liệu trong nền, trong khi trình kết xuất chỉ hoạt động với những gì bạn nhìn thấy. Các khối 8x8 sẽ dễ dàng hơn để xử lý.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.