2010-06-12 27 views
7

Trong Java (Swing), nói rằng tôi có một trò chơi 2D, nơi tôi có nhiều loại thực thể khác nhau trên màn hình, chẳng hạn như người chơi, kẻ xấu, powerups, v.v. người chơi di chuyển trên màn hình, để kiểm tra hiệu quả những gì đang ở trong vùng lân cận của người chơi, tôi nghĩ tôi muốn truy cập chỉ mục vào những thứ gần nhân vật dựa trên vị trí của họ.Ánh xạ hiệu quả các vị trí thực thể trò chơi trong Java

Ví dụ, nếu người chơi 'P' bước vào yếu tố 'E' trong ví dụ sau ...

| | | | | | 
| | | |P| | 
| | |E| | | 
| | | | | | 

... sẽ làm điều gì đó như:

if(player.getPosition().x == entity.getPosition().x && 
       entity.getPosition.y == thing.getPosition().y) 
{ 
    //do something 
} 

Và thats tốt, nhưng điều đó ngụ ý rằng các thực thể giữ vị trí của họ, và nếu tôi có MANY thực thể trên màn hình tôi sẽ phải lặp qua tất cả các thực thể có sẵn và kiểm tra từng vị trí chống lại vị trí người chơi. Điều này có vẻ thực sự không hiệu quả đặc biệt là nếu bạn bắt đầu nhận được tấn của các thực thể.

Vì vậy, tôi sẽ nghi ngờ tôi muốn một số loại bản đồ như

Map<Point, Entity> map = new HashMap<Point, Entity>(); 

Và lưu trữ thông tin quan điểm của tôi ở đó, vì vậy mà tôi có thể truy cập vào các thực thể trong thời gian liên tục. Vấn đề duy nhất với cách tiếp cận đó là, nếu tôi muốn chuyển một thực thể đến một điểm khác trên màn hình, tôi phải tìm kiếm thông qua các giá trị của HashMap cho thực thể mà tôi muốn di chuyển (không hiệu quả vì tôi không biết nó Vị trí điểm trước thời hạn), và sau đó một khi tôi đã tìm thấy nó loại bỏ nó từ HashMap, và chèn lại nó với các thông tin vị trí mới.

Bất kỳ đề xuất hoặc lời khuyên nào về cấu trúc dữ liệu/định dạng lưu trữ nào tôi phải sử dụng ở đây để có quyền truy cập hiệu quả vào các thực thể dựa trên vị trí của chúng cũng như vị trí dựa trên thực thể?

Trả lời

4

Phân vùng không gian có thể có hiệu quả.

Bạn có thể thực hiện các bộ phận cố định, chẳng hạn như lưới đồng nhất hoặc lưới có trọng số nếu bạn ngoại trừ có các điểm nóng trên bản đồ của bạn nơi mọi thứ được nhóm bất thường. Đối với mỗi phân vùng bị chiếm đóng, hãy tạo một vùng chứa của tất cả các thực thể mà nó chứa.

Chèn là thời gian cố định. Loại bỏ là một phần thực tế vô hạn của n (tổng số thực thể của bạn) giả định n là rất lớn và bạn đã thiết lập phân vùng của mình một cách hiệu quả. Tra cứu vùng lân cận chia sẻ cùng thời gian chạy như các lần xóa. Tuy nhiên, về mặt kỹ thuật, O ( n) tuy nhiên phần nhỏ lại là nhỏ. Điều này sẽ trở nên rõ ràng nếu một phân vùng trở nên bất thường đông đúc.

Để có được một danh sách tất cả các đơn vị trong phạm vi x đơn vị của một tổ chức nào, trước tiên bạn phải có được một danh sách tất cả các phân vùng mở rộng ra bởi 2 x vuông vuông rộng tập trung vào tổ chức của bạn. Nếu bạn sử dụng một phân vùng lưới, điều này là khá tầm thường.Tiếp theo, bạn lặp qua tất cả các thực thể trong các phân đoạn đó và trả về mỗi thực thể có khoảng cách là x hoặc ít hơn cho thực thể được đề cập.

Một phương pháp phân vùng phức tạp hơn là tự động phân vùng không gian trong một cây, đảm bảo rằng không có phân vùng nào có thể chứa nhiều hơn một số thực thể nhất định. Nếu một phân vùng đầy, bạn phân chia nó dọc theo trung bình không gian và tạo hai phân vùng không gian sao cho mỗi phân vùng chứa một nửa các thực thể của phân vùng gốc. Điều này làm cho chèn và tra cứu có thời gian chạy logarit vì bạn không còn có thể khám phá các phân vùng mong muốn trong thời gian không đổi, nhưng việc loại bỏ trở thành thời gian không đổi cho các quần thể phân vùng mũ.

+0

Cảm ơn lời khuyên, tôi sẽ nghiên cứu phân vùng không gian hơn. –

+0

Tôi sắp xếp hai bản cài đặt bảng trò chơi để chứa 1.000.000 thực thể được thêm ngẫu nhiên vào khu vực 1920x1080. Sử dụng một vùng chứa 1080x1920, tôi đã có 0,004 ms để chèn, 0,003 ms khi xóa và 0,00 ms để yêu cầu danh sách tất cả vùng chứa trong vùng 3x3. Sử dụng phân vùng không gian nhị phân động, tôi đã chèn 0,007 ms, 0,003 ms xoá và 0,007 ms truy vấn cho các phân vùng giao nhau với vùng 3x3. Hiệu suất và mức sử dụng bộ nhớ trên BSP sẽ tốt hơn đối với các thực thể không được phân bổ thống nhất. – Gunslinger47

0

kém hiệu quả kể từ khi tôi không biết vị trí điểm của nó trước thời hạn
Tôi thích hợp, mà đối tượng thực thể không có thông tin vị trí trong nó? Tôi sẽ đề nghị thêm nó. Hoặc, nếu không, bạn có thể có bản đồ các vị trí thực thể hiện tại Map<EntityIdType, Point> và tìm nạp vị trí trước tiên. Không có gì lạ mắt.

+0

Hoặc bạn vừa mới giải quyết vấn đề trong tầm tay hoặc bạn không hiểu đầy đủ câu hỏi, vì không có giải pháp nào được cung cấp tại đây. Dựa trên 2 phương pháp được đề xuất trong bài gốc, đối tượng có hoặc không chứa thông tin vị trí. Tương tự, Bản đồ phụ thuộc vào cách tiếp cận nào đã được thực hiện. Dù bằng cách nào thì vấn đề ban đầu của việc tìm kiếm nền tảng trung bình không có trong câu trả lời của bạn. –

3

Nếu có một ánh xạ một đối một giữa EntityPoint và bạn muốn có thể ánh xạ theo cả hai hướng, thì bimap là cấu trúc dữ liệu tự nhiên nhất.

Ổi có triển khai BiMap<K,V>, hỗ trợ thao tác xem BiMap<V,K> inverse(). Nó chỉ là một cái nhìn, vì vậy nó không tốn kém chút nào.

Hoặc bạn có thể quản lý Map<Entity,Point>Map<Point,Entity> của riêng mình, nhưng điều đó sẽ là phát minh lại bánh xe.

Các vấn đề liên quan