Cách thích hợp để xử lý sự phá hủy của các thực thể trò chơi


10

Hãy tưởng tượng một thế giới trò chơi nơi tải và tải các thực thể được tải động mọi lúc, tôi sẽ biểu thị đó là một danh sách các thực thể có lẽ, nhưng còn việc loại bỏ chúng thì sao?

Trong khi thêm tôi có thể đẩy lùi thực thể mới, tôi có thể cần phải loại bỏ bất cứ nơi nào trong container. Để tránh tìm kiếm phần tử để tìm vị trí của nó để loại bỏ, tôi có lựa chọn nào?

Tôi nghĩ rằng tôi có thể lưu trữ id thực thể là vị trí của nó trong vùng chứa, tạo đường dẫn để loại bỏ trực tiếp, nhưng liệu điều đó có tạo ra một loại 'rối loạn' phụ thuộc lẫn nhau không?

Tôi biết cách đúng sẽ là một cái gì đó giống như List.RemoveAt (whereToRemove); Nhưng nếu chỉ có thực thể biết khi nào thì nó sẽ chết?

Hay tôi chỉ thiếu một cái gì đó và một thùng chứa danh sách sẽ biết khi nào một đối tượng bị phá hủy và giảm kích thước của chính nó?

Câu trả lời:


10

Đây là điều kiện của bạn:

  • Các đối tượng khác vẫn có thể phụ thuộc vào thực thể bị xóa của bạn, sau khi nó bị xóa.

  • Bạn chỉ muốn thực thể chỉ định loại bỏ nó.

Bạn không thể có cả hai. Tại sao? Bởi vì mã ở mức cao hơn chính thực thể của bạn (xem ví dụ bên dưới) quyết định khi nào thực thể đó cần được sử dụng. Do đó, chỉ mã ở cùng cấp đó có thể xác định liệu thực thể của bạn có phù hợp để xóa hay không.

Tuy nhiên , điều có thể xảy ra là thực thể có thể yêu cầu xóa chính nó, bằng cách khởi động một sự kiện mà mã cấp cao hơn đang lắng nghe. Mức cao hơn sau đó lưu trữ yêu cầu này để loại bỏ trong một danh sách.


Ví dụ 1: không có sự kiện

Bạn đang kiểm tra va chạm giữa các thực thể trong thế giới của bạn. Điều này được xử lý cao hơn, thường là trong vòng lặp trò chơi chính của bạn, kiểm tra mọi thực thể đối với nhau. Trong ví dụ này cụ thể, khi một thực thể va chạm với một thực thể khác, chỉ logic bên trong của thực thể đó có thể xác định mức độ thiệt hại của nó và liệu nó có "hết hạn" hay không. Vì vậy, hãy theo dõi luồng logic cho các va chạm trong đó bạn có bốn thực thể trong thế giới của mình, A, B, C và D. A là thực thể của chúng tôi mà chúng tôi quan tâm.

Chúng tôi kiểm tra A để va chạm với B. Có va chạm. A nhận sát thương 50%.

Chúng tôi kiểm tra A để va chạm với C. Có va chạm. A nhận sát thương 50%. Vì sát thương đạt 0, A xác định rằng nó đã "chết". Nó loại bỏ chính nó khỏi danh sách.

Chúng tôi kiểm tra A để va chạm với D. Sẽ không có xung đột, nhưng bạn sẽ không bao giờ đi xa đến thế: bạn có một ngoại lệ thời gian chạy vì danh sách thực thể của bạn đã được sửa đổi ở giữa hoạt động traver.

Ví dụ 2: với các sự kiện

Thiết lập tương tự như trước đây.

Chúng tôi kiểm tra A để va chạm với B. Có va chạm. A nhận sát thương 50%.

Chúng tôi kiểm tra A để va chạm với C. Có va chạm. A nhận sát thương 50%. Vì sát thương đạt 0, A xác định rằng nó đã "chết". Nó kích hoạt một sự kiện tới mã quản lý thực thể để nói, "Loại bỏ tôi càng sớm càng tốt". Mã quản lý thực thể xem tham chiếu thực thể được gửi như một phần của sự kiện và lưu trữ tham chiếu đó trong danh sách các thực thể cần xóa.

Chúng tôi kiểm tra A để va chạm với D. Không có va chạm và kiểm tra hoạt động tốt.

Bây giờ, ở phần cuối của vòng lặp trò chơi hiện tại , hãy chạy qua danh sách các thực thể cần xóa và xóa mọi thứ trong số chúng khỏi danh sách các thực thể chính của bạn.


Bạn có thể thấy làm thế nào điều này tránh được vấn đề hoàn toàn. Bạn không cần sử dụng các sự kiện, bạn có thể sử dụng tín hiệu hoặc thứ gì khác, nhưng nguyên tắc là như nhau - không xóa các thực thể cho đến khi bạn có thể làm như vậy một cách an toàn. Điểm nổi bật của cách tiếp cận này, để giữ mọi thứ sạch sẽ và có trật tự, đang làm tương tự với các thực thể cần thêm - đảm bảo bạn giữ các tham chiếu đến chúng và chỉ thêm chúng khi bắt đầu vòng lặp trò chơi tiếp theo.

Cuối cùng, đừng quên xóa cả danh sách cần xóa và danh sách cần thêm của bạn, mỗi lần bạn sử dụng chúng để thực hiện bổ sung / xóa trên danh sách thực thể chính của mình.

Tái bút Đừng ngại tìm kiếm trong danh sách chính của bạn để thực hiện xóa cá nhân. Đó là một phần và phần của quản lý thực thể, và thậm chí các danh sách lớn có xu hướng rất nhanh để vượt qua - sau tất cả, đó là những gì họ được thiết kế cho.


0

Bạn chắc chắn đang tìm kiếm HashMap / HashTable . Hashtable là bản đồ khớp với khóa với một giá trị cụ thể. Khóa có thể là bất cứ thứ gì (chẳng hạn như ID thực thể).


0

Tôi đoán bạn có thể sử dụng ý tưởng con trỏ thông minh để xử lý các thỏa thuận cho bạn, trong trường hợp đó sẽ không cần phải giữ một danh sách tất cả các thực thể trong mã của bạn.

trong một số trường hợp, bạn cần một danh sách để lặp lại tất cả các đối tượng trong trò chơi của bạn. danh sách này có thể chỉ đơn giản là một danh sách liên kết trong đó việc chèn và xóa các đối tượng khỏi nó sẽ mất chính xác thời gian O (1).

thậm chí để tăng tốc độ của bạn nhiều hơn, bạn có thể sử dụng một số mảng tĩnh (có thể là một vectơ). trong trường hợp đó, bạn sẽ cần theo dõi 2 danh sách được liên kết trong cùng một vectơ, một danh sách sẽ lặp lại trên các đối tượng hợp lệ và một danh sách sẽ lặp lại trên các đối tượng miễn phí. Bất cứ khi nào con trỏ thông minh đánh dấu một số vị trí cần xóa, bạn chỉ cần xóa con trỏ đó và thêm không gian đó vào danh sách không gian trống. và bất cứ khi nào bạn thêm một số thực thể, bạn chỉ cần xóa tự do đầu tiên điền vào nó bằng con trỏ thực thể và sau đó thêm nó vào danh sách các đối tượng hợp 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.