Referencing Dynamicly Created Bodies

Topics: Developer Forum, User Forum
Jul 21, 2011 at 4:01 PM

Hi Guys just a quicky question...

I am creating a bunch of rectangles dynamically and by that i mean like this:

for (int x = 0; x < 10; x++)
for (int y = 0; y < 10; y++)
{
Vector2 groundPosition = new Vector2((x * 0.25f), (y * 0.25f));

testBody = BodyFactory.CreateRectangle(Game1._world, 0.25f, 0.25f, 1f, groundPosition, Color.Black);
testBody.Restitution = 0.3f;
testBody.Friction = 3f;
}

So as you can see there are 100 rectangles that have been created there, problem is that i want to be able to reference say block 55 to do something.

Currently in my understanding i could write:

testBody.ApplyLinearImpulse(new Vector2(2,2));

but that only applys to the last body that was created...

Is there a way to be able to say testBody55 do this...

I thought about creating an array of bodys so i could reference them then, it work well, but on a large game map i ran out of PC memory!

Jul 21, 2011 at 9:01 PM

It may be perfectly reasonable what you're doing, but could you give a little bit more details of what it is you're trying to achieve?

An array sounds like a perfect solution as you can randomly access any of your bodies using their index, though you can also use a 2D array so you can reference say 5, 5 instead of calculating that square with 5*y+x.

But making a map like this may not be such a good idea. With a little more information someone might be able to suggest a better solution without having to create hundreds of bodies.

Jul 21, 2011 at 9:33 PM
List<Body> list=new List<Body>();
for (int x = 0; x < 10; x++)
for (int y = 0; y < 10; y++)
{
Vector2 groundPosition = new Vector2((x * 0.25f), (y * 0.25f));

testBody = BodyFactory.CreateRectangle(Game1._world, 0.25f, 0.25f, 1f, groundPosition, Color.Black);
testBody.Restitution = 0.3f;
testBody.Friction = 3f;
list.Add(testBody);
}

list[55].Apply.LinearImpulse(new Vector2(12,12));
Jul 22, 2011 at 3:08 AM

@Grave, I am not sure what information i can give you... i am trying to create a game that has a full "physics" world / feel. So i thought to use Farseer for...just about everything.

Its obviously a tile based map, that will work like the game Terraria, I noticed that i can create a full map of Bodys it just either crashes (no ram) or it runs at about 15FPS...

So i am trying to limit the loading of the Bodys as the character moves about the world.

@SeriousSam909, Thats basically what i did with the array, but i have not used a list before... are there benefits to a list? faster than a [,] array?

Everything was going well until i tried to create an array of Bodys that was 800 x 800, i wasn't actually creating the Bodys in the array at that point just creating references, and it still crashed.

Developer
Jul 22, 2011 at 3:38 AM

@MalakiG: It is not possible to have that many bodies running in the simulation at once. Terraria uses a very simple and specific style of physics for it's game play, there are no rotational dynamics, this offers a huge processing advantage as they can always count on everything being oriented a certain way. Your best bet would probably be to only use Farseer for the dynamic objects, i.e. - bombs, arrows, body parts... And design some sort of algorithm to convert the visible (static - tiles) section of your world into a simple set of convex meshes. I once created a track that was over a mile long (to scale) and a tank to drive along it and performance was terrible because my track had approximately 2500+ edges. I ended up dynamically adding newly visible pieces of the track and removing pieces no longer visible and ended up with just a 100 or so edges on screen at once and no lag at all. Getting a huge world to behave well with a physics engine is quite difficult and requires quite a bit of finesse.

If I was you I would do a search for Terraria's source code and take a look. It's a little hard to read, but you can see how much work went into making it performance friendly to have 8400 blocks wide and 2400 blocks tall.

Jul 22, 2011 at 3:55 AM

@MattBettcher, Cheers for the info, i guess i wanted to use Farseer because the collision detection ect was so good... hmm might need to re think this...I am going to try one last idea similar to your 1 mile track example and if that does not work then start again...lol

Ill look up the source code for Terraria if its freely available and have a tinker...

Again thanks for the reply.

Jul 22, 2011 at 2:40 PM

Mattbettcher has probably got the best advise here, but I thought I'd post again for the 'list' question.

For what you're doing an array (either 1D or 2D) is fine. Your map isn't going to expand and it means you can easily index each square of the map. A list, unless it's different in .NET than it is everywhere else, can only be accessed in sequence. So even doing list[50] means you've got to go through 49 other elements before you reach 50, which isn't as efficient as an array. I may be wrong, but that's how a list usually works. Not having a fixed memory size causes issues with indexing because where is element 50? Could be anywhere, but element 49 should point to it, and 48 points to that and so forth...

Jul 22, 2011 at 3:03 PM

@Grave, Perfect thanks, so really a list is kinda like a single []array.

So it will take "time" for it to find 50, it needs to go through 1,2,3,4.... then to 50? wow i can see how that will not work as effectively here.

Again thanks to all you guys for the advise!