Lý lịch
Cùng với một người bạn tôi đang làm việc trong một trò chơi 2D được đặt trong không gian. Để làm cho nó trở nên nhập vai và tương tác nhất có thể, chúng tôi muốn có hàng ngàn vật thể tự do trôi nổi xung quanh, một số cụm lại với nhau, một số khác di chuyển trong không gian trống.
Thử thách
Để giải phóng công cụ kết xuất và vật lý, chúng ta cần thực hiện một số loại phân vùng không gian. Có hai thử thách chúng ta phải vượt qua. Thách thức đầu tiên là mọi thứ đều chuyển động nên việc xây dựng lại / cập nhật cấu trúc dữ liệu phải cực kỳ rẻ vì nó sẽ phải được thực hiện ở mọi khung hình. Thách thức thứ hai là phân phối các vật thể, như đã nói trước đó có thể có các cụm vật thể với nhau và các khoảng trống lớn và để làm cho nó thậm chí còn tệ hơn không có ranh giới với không gian.
Công nghệ hiện có
Tôi đã xem xét các kỹ thuật hiện có như BSP-Plants, QuadTrees, kd-Plants và thậm chí R-Plants nhưng theo tôi có thể nói các cấu trúc dữ liệu này không phù hợp hoàn hảo vì cập nhật nhiều đối tượng đã di chuyển sang các ô khác là tương đối đắt tiền.
Những gì tôi đã thử
Tôi đã đưa ra quyết định rằng tôi cần một cấu trúc dữ liệu hướng đến việc chèn / cập nhật nhanh hơn là trả lại số lần truy cập ít nhất có thể được cung cấp cho một truy vấn. Với mục đích đó, tôi đã tạo ra các ô ẩn để mỗi đối tượng, với vị trí của nó, có thể tính toán được các ô đó sẽ nằm ở đâu. Sau đó, tôi sử dụng một HashMap
ánh xạ tọa độ ô đến một ArrayList
(nội dung của ô). Điều này hoạt động khá tốt vì không có bộ nhớ bị mất trên các ô 'trống' và dễ dàng tính toán các ô nào cần kiểm tra. Tuy nhiên, việc tạo ra tất cả những thứ đó ArrayList
(trường hợp xấu nhất N) rất tốn kém và vì vậy nó đang tăng lên HashMap
rất nhiều lần (mặc dù điều đó được giảm nhẹ bằng cách cho nó một công suất ban đầu lớn).
Vấn đề
OK để nó hoạt động nhưng vẫn không nhanh. Bây giờ tôi có thể cố gắng tối ưu hóa vi mã JAVA. Tuy nhiên tôi không mong đợi quá nhiều về điều đó vì trình hồ sơ cho tôi biết rằng phần lớn thời gian được dành để tạo ra tất cả những đối tượng mà tôi sử dụng để lưu trữ các tế bào. Tôi hy vọng rằng có một số thủ thuật / thuật toán khác hiện có giúp việc này nhanh hơn rất nhiều vì vậy đây là cấu trúc dữ liệu lý tưởng của tôi trông như sau:
- Ưu tiên số một là cập nhật / tái cấu trúc nhanh toàn bộ cấu trúc dữ liệu
- Việc phân chia các đối tượng thành các thùng có kích thước bằng nhau, điều quan trọng hơn là chúng ta có thể vẽ thêm một vài đối tượng và thực hiện thêm một số kiểm tra va chạm nếu điều đó có nghĩa là việc cập nhật nhanh hơn một chút
- Bộ nhớ không thực sự quan trọng (trò chơi trên PC)