2015-09-21 2 views
0

Я использую MonoGame, чтобы сделать небольшую игру как практику. ты корабль и стреляй астероидами с пулями.Как удалить конкретный неповторимый объект в списке, не зная его индекса

У меня есть объект, который я могу снимать, а затем он взрывается в кучу пуль, все это работает, за исключением удаления оригинального объекта бомбы.

Я обрабатываю свои объекты в списке, где объектом является объект, на который наследуются все объекты в списке (например, корабль, астероид, пуля и т. Д.), Поэтому я могу просто поместить их в 1 список и поставить индексы в чистом списке, когда они сталкиваются, перебирают это и удаляют элементы из исходного списка с индексами, которые находятся в чистом списке.

TL; DR Проблема заключается в том, что я не знаю, как отслеживать конкретные объекты бомбы со списком только с его индексом, потому что все объекты удаляются и добавляются все время.

Если я пытаюсь использовать какой-то таймер в объекте Bomb, я не могу удалить его из самого объекта, я даже попытался вызвать внешний метод Finalize, чтобы установить объект в NULL, но это тоже не сработало. Я использовал эту строку кода:

game.objectController.Finalize(this); 

и этот метод:

public void Finalize(Entity obj) 
{ 
    obj = null; 
} 

один трудным решением было бы сделать какой-то метод, который уследить всех индексов в EntityList, даже они «перемещаются», но это не правильный способ справиться с этим, не так ли?

Другое решение, о котором я мог думать, это что-то сделать с объекта бомбы, который вернет его запись в список, но у меня нет ЛЮБОЙ идеи, как это сделать.

Заранее благодарим за помощь.

редактировать: это код, который я пытался как интерфейс

interface IDestructible 
{ 
public bool Isdestroyed(); 
} 

и это реализуется метод, который я использую в разрушаемого объекта, который я хочу уничтожен после определенного TimeLimit:

public bool IDestructible.Isdestroyed(){ 
    if (timer == 25) 
    { 
     Explode(); 
     return true; 
    } return false; 
}` 

ответ

1

Исходный объект bullet в некотором роде особенный, поэтому вы можете заставить его реализовать определенный интерфейс или быть производным классом. Например, вы можете создать такой интерфейс:

public interface IDestroyable 
{ 
} 

Тогда вы могли бы пройти по списку и проверить во время выполнения какого элемента реализует интерфейс с оператором is. И удалите его.

public class SourceBullet : Entity, IDestroyable 
{ 
    // whatever 
} 

А теперь:

foreach (var item in myList) 
{ 
    if (item is IDestroyable) 
    { 
     myList.Remove(item); 
    } 
} 

Таким образом, вам не нужно следить за объектом все время. Наследуя от Entity, исходная пуля все еще может быть частью списка, но вы сможете отличить ее от других пуль.

+0

Интересно, я полагаю, что мог бы даже поставить виртуальный метод проверки таймера в объекте бомбы, и если он вернет истину, я удалю его, не так ли? – stickypatrol

+0

@stickypatrol Уверен, вы можете :-) – Kapol

+0

Я пробовал это решение и не могу заставить его работать. проблема в том, что я прокручиваю список объектов Entity (общий базовый класс), а объекты объекта не все имеют общий метод, который проверяет время, я могу реализовать интерфейс следующим образом: '(IDestructible) entityList [ p] .' , но я не могу использовать этот метод из интерфейса. – stickypatrol

0

Когда я был в подобной ситуации, без использования игрового движка, то, что я закончил, заключалось в том, что каждый объект отслеживает его собственное состояние, а затем цикл проходит через все объекты, чтобы очистить их в конце основного игрового цикла.

class gameobject 
{ 
    public bool isDestroyed {get;set;} 
} 
class bomb : gameobject 
{ 
} 

main loop update: 

for(i = gameobjectcollection.Length; i--; i > -1) 
{ 
    if(gameobjectcollection[i].isDestroyed) gameobjectcollection[i] = null;//or whatever to remove by index 
} 
+0

Но тогда я должен был бы добавить эту переменную для каждого объекта, который наследует от Entity, хотя используется только 1 objecttype. разве это не считается плохой практикой? – stickypatrol

+0

В моем случае, поскольку каждый объект был игровым объектом, и каждый объект может быть уничтожен в конце концов (кроме нескольких, таких как табло), имеет смысл иметь его. У вас может быть подкласс разрушаемых объектов и просто пропустить их, то есть gameobjects.where (go => typeof (go) уничтожается) (псевдокод) – SumGuy

+0

Я вижу. Интересно, спасибо. – stickypatrol