0

I'm using MonoGame to make a little game as practice. you're a ship and shoot asteroids with bullets.

I have an object that I can shoot and then it explodes into a bunch of bullets, it all works except for the removal of the original bomb object.

I handle my objects in a List where entity is the object that all the objects in the list(such as ship, asteroid, bullet etc) inherit from, I do that so I can just put them in 1 list and put the indexes on a cleanlist when they collide, loop through that and remove the items from the original list with the indexes that are in the cleanlist.

TL;DR the problem is, I don't know how to keep track of specific bomb objects with a list with just it's index because different objects are being removed and added all the time.

if I try to use some sort of timer in the Bomb object I can't delete it from the object itself, I even tried calling an outside method Finalize to set the object to NULL but that didn't work either. I used this line of code:

game.objectController.Finalize(this);

and this method:

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

one difficult solution would be to make some kind of method that keep track of all the indexes in the entitylist, even as they 'move around' but that's not the correct way to handle it is it?

another solution I could think of is perform something from the bomb object that will return it's list entry, but I don't have ANY idea how to do that.

thanks in advance for your help.

edit: this is the code that I tried as an interface

interface IDestructible
{
public bool Isdestroyed();
}

and this is the implemented method that I use in the destructible object that I want destroyed after a certain timelimit:

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

2 Answers2

1

The original bullet object is in some way special, so you could make it implement a specific interface or be a derived class. You could for example create such an interface:

public interface IDestroyable
{
}

Then you could traverse the list and check at runtime which element implements the interface with the is operator. And remove it.

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

And now:

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

This way you don't need to keep track of the object all the time. By inheriting from Entity, the original bullet can still be a part of the list, yet you will be able to distinguish it from other bullets.

Kapol
  • 6,383
  • 3
  • 21
  • 46
  • Interesting, I suppose I could even put in a virtual method to check for the timer in the bomb object and if it returns true I remove it, couldn't I? – stickypatrol Sep 21 '15 at 17:32
  • @stickypatrol Sure you can :-) – Kapol Sep 21 '15 at 17:33
  • I tried this solution and can't seem to get it to work. the problem is that I loop through a list of Entity objects(the common base class) and the entity objects don't all have a common method that checks for the timing, I can implement an interface like so: `(IDestructible)entityList[p].` but I can't use the method from the interface. – stickypatrol Sep 21 '15 at 20:19
  • @stickypatrol Looks like you need to do `if (item is IDestructable) { ((IDestructable)item).Destroy() }`. The way you wrote it, you are first calling the method/property on an `Entity` object and casting the result of this call to an `IDestructable`. Note also that implementing and casting are two totally different things. – Kapol Sep 21 '15 at 22:07
0

When I was in a similar situation, without using a game engine, what I ended up doing was have each object keep track of it's own state, then have a loop run through all the objects to clean them up at the end of the main game loop.

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
}
SumGuy
  • 602
  • 7
  • 18
  • But then I would have to add that variable for each object that inherites from Entity even though only 1 objecttype uses it. isn't that considered bad practice? – stickypatrol Sep 21 '15 at 17:35
  • In my case, since every object was a game object, and every object could be destroyed eventually (except a few like the scoreboard) it made sense to have it. You could have a subclass of destroyable objects and just loop through those, ie gameobjects.where(go=>typeof(go) is destroyable) (pseudocode) – SumGuy Sep 21 '15 at 17:39