Правильний спосіб впоратися зі знищенням ігрових утворень


10

Уявіть собі ігровий світ, де навантаження та навантаження сутностей динамічно завантажуються весь час, я б представляв це як список сутностей, але що робити з їх видаленням?

Хоча при додаванні я міг би відштовхувати нову сутність, у мене могла виникнути потреба видалити де-небудь з контейнера. Щоб уникнути пошуку елемента, щоб знайти його місце для видалення, які варіанти я маю?

Мені здалося, що я можу зберігати ідентифікатор сутності як його позицію в контейнері, створюючи шлях для прямого видалення, але не буду, що генерує якийсь "розлад" взаємної залежності?

Я знаю, що правильним шляхом було б щось на зразок List.RemoveAt (whereToRemove); але що робити, якщо тільки суб'єкт знає, коли він повинен померти?

Або мені просто щось не вистачає, і контейнер списку знає, коли об’єкт знищений і зменшить його власний розмір?

Відповіді:


10

Ось ваші умови:

  • Інші об'єкти все ще можуть залежати від видаленого об'єкта після його вилучення.

  • Ви хочете, щоб лише організація вказала, що це власне видалення.

Ви не можете мати обох. Чому? Оскільки код на більш високому рівні, ніж ваша сутність (див. Приклади нижче), визначає, коли цю сутність потрібно використовувати. Отже, лише код на тому самому рівні може визначити, чи підходить ваша організація для видалення чи ні.

Однак , що може статися, це те, що суб'єкт господарювання може подати запит на власне видалення, звільнивши подію, яку слухає код вищого рівня. Цей вищий рівень зберігає цей запит на видалення у списку.


Приклад 1: без подій

Ви перевіряєте зіткнення між сутностями у вашому світі. Це обробляється вище вгору, як правило, у вашому головному циклі гри, який перевіряє кожну сутність один проти одного. У цьому прикладі конкретно, коли суб'єкт господарювання стикається з іншим, лише внутрішня логіка суб'єкта господарювання може визначити, скільки шкоди вона заподіяла та чи "чи не втратила чинність". Тож давайте слідкувати за потоком логіки для зіткнень, коли у вас є чотири сутності у вашому світі, A, B, C та D. A - це наша сутність, про яку ми маємо справу.

Перевіряємо A на зіткнення з B. Відбувається зіткнення. А завдає шкоди 50%.

Перевіряємо A на зіткнення з C. Відбувається зіткнення. А завдає шкоди 50%. Оскільки збиток досягає 0, A визначає, що він "загинув". Він видаляє себе зі списку.

Ми перевіряємо A на зіткнення з D. Зіткнення не було б, але ви ніколи не заїдете так далеко: ви отримаєте виняток із часу виконання, оскільки список ваших організацій був змінений у розпал подорожньої операції.

Приклад 2: з подіями

Таке ж налаштування, як і раніше.

Перевіряємо A на зіткнення з B. Відбувається зіткнення. А завдає шкоди 50%.

Перевіряємо A на зіткнення з C. Відбувається зіткнення. А завдає шкоди 50%. Оскільки збиток досягає 0, A визначає, що він "загинув". Він запускає подію до коду управління суттю та каже: "Видаліть мене якнайшвидше". Код управління суттю розглядає посилання на об'єкт, надісланий як частину події, і зберігає цю посилання у списку об'єктів, які потрібно видалити.

Ми перевіряємо А на зіткнення з D. Зіткнення немає, і перевірка працює просто чудово.

Тепер, в самому кінці поточної ітерації циклу гри, пройдіть список списків об'єктів, які потрібно видалити, і видаліть кожне з них із вашого основного списку сутностей.


Ви можете бачити, як це взагалі уникає проблеми. Вам не потрібно використовувати події, ви можете використовувати сигнали чи щось інше, але принцип той самий - не видаляйте об'єкти, поки не зможете безпечно це зробити. Для того, щоб все було в чистоті та впорядкованості, робимо те ж саме, що і суб'єкти, щоб додати - переконайтеся, що ви зберігаєте посилання на них та додаєте їх лише на початку наступної ітерації циклу гри.

Нарешті, не забудьте промити як списки для видалення, так і списки для додавання кожного разу, коли ви використовуєте їх для виконання доповнень / видалень у вашому головному списку сут.

PS. Не бійтеся шукати свого основного списку, щоб зробити окремі видалення. Це невід'ємна частина управління суб'єктами господарювання, і навіть масові списки, як правило, дуже швидко проходять - адже саме для цього вони розроблені.


0

Ви точно шукаєте HashMap / HashTable . Хештеб - це карта, яка відповідає ключу до певного значення. Ключем може бути все, що завгодно (наприклад, ідентифікатор особи).


0

Я здогадуюсь, ви могли б використовувати ідею smartpointer, щоб обробляти місця розташування для вас, у цьому випадку не буде необхідності зберігати список усіх об'єктів у вашому коді.

в деяких випадках вам потрібен список для перегляду всіх об’єктів у вашій грі. цей список може бути просто списком посилань, де вставлення та видалення з нього об’єктів займе рівно O (1) час.

навіть щоб збільшити швидкість, ви можете використовувати якийсь статичний масив (можливо, вектор). у такому випадку вам потрібно буде відслідковувати 2 пов’язані списки всередині одного вектора, один повторюватиметься над дійсними об’єктами, а один повторюватиметься над вільними об’єктами. щоразу, коли smartpointer відзначає якесь місце, яке потрібно видалити, ви просто видаляєте цей покажчик і додаєте простір до списку вільних пробілів. і щоразу, коли ви додаєте якусь сутність, вам потрібно лише видалити перший вільний простір, заповнити його покажчиком сутності, а потім додати його до дійсного списку об'єктів

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.