Clearing the world

General discussion about Box2D tutorials
Post Reply
MattF
Posts: 6
Joined: Mon Jan 07, 2013 1:52 pm

Clearing the world

Post by MattF »

Heya.

I have a little problem with clearing the world from all the bodies.

During my game, when enemies die, they are removed after some time, similar to "removing bodies safely". It works just fine. But when i switch the level i want to clear all the bodies from the world, delete old level and create new one. Next level loads up, but when i interact with any enemy, it crashes, while debugger points to methods from contact listener( based on tutorial). I wanted to ask if my way of clearing all the bodies is fine, so the problem is elsewhere, like dangling pointers for enemies vector.

Here's the code for destructor of a level:

Code: Select all

Level::~Level()
{	
	delete ui;
	delete damageResolver;
	delete camera;
	delete hero;
	delete ls;
	delete door;
	
	std::vector<b2Body*> bodies;
	for (std::vector<Enemy*>::iterator it = enemies.begin() ; it != enemies.end(); it++)
		{
			delete (*it);
		}
	for ( b2Body* b = world->GetBodyList(); b != NULL; b = b->GetNext())
	{
		//bodies.push_back(b);
		world->DestroyBody(b);
	}
	/*for (std::vector<b2Body*>::iterator it = bodies.begin() ; it != bodies.end(); it++)
	{
		world->DestroyBody(*it);
	}*/
	enemies.clear();
	bodies.clear();
}
As you can see i tried either just removing directly from world list, or pushing all the pointers to another vector which i use to destroy all bodies.

Thanks in advance;)
iforce2d
Site Admin
Posts: 861
Joined: Sat Dec 22, 2012 7:20 pm

Re: Clearing the world

Post by iforce2d »

If you're going to destroy every body in the world, you might as well just destroy the world itself because you get the same effect, but faster because Box2D can delete all the bodies it holds with one delete call, due to how it stores them.

You could accomplish the latter part of that destructor with:

Code: Select all

for (int i = 0; i < enemies.size(); i++)
    delete enemies[i];
enemies.clear();

delete world;
world = NULL;
The last line is not really necessary but it helps when you're debugging, because you can see that the pointer is NULL and it is clearly invalid, as opposed to seeing something like 0x4a8e7df6 which is not always that obvious.

I notice that the second loop, will end up doing this:
world->Destroy(b);
b = b->GetNext(); // but... b was just destroyed

However, since you say that the crash occurs when you next interact with an enemy, this is probably not the cause of the crash. When you delete all those Enemy pointers, make sure there is nowhere else in the code that has a reference to them still. Well... same goes for everything else that you're deleting at the beginning of the function too.
MattF
Posts: 6
Joined: Mon Jan 07, 2013 1:52 pm

Re: Clearing the world

Post by MattF »

That worked, thanks;)
Post Reply