2
\$\begingroup\$

Here is my issue.

I currently have Box2D setup and working. But, it works with my Entity system. So I can create static objects and dynamic moving ones, and they simulate fine.

However, my world is made up of tiles.

I have very easy ways of determining which Tiles a Body is intersecting, but I'm not sure how to tell this to Box2D.

I could obviously turn each tile into a Body but that would waste a lot of ram because I have 10s of thousands of tiles.

The tiles also form some cool patterns and can be converted to an empty tile at will.

My thought was to do something like this:

-Iterate the bodies, find which tiles they are touching, add these as static bodies into the world. Step the world. Remove the bodies.

This seems like a bit of a hack though and I am wondering if anyone can think of a better way.

Thanks

\$\endgroup\$
  • \$\begingroup\$ trace the bounds of the tilemap world and create a body with multiple b2ChainShape to form the boundaries of the world \$\endgroup\$ – LearnCocos2D Jan 2 '14 at 14:09
3
\$\begingroup\$

I've done the same thing a few years ago.

The solution was to initialize a Pool of Body Objects, and then position them all off screen. The idea is to create a set amount of bodies, and then move them around when required. I managed to locate my old code, here is the initialization code from my old project:

private void InitializeBodyPool()
{
    Bodies = new Pool<LandBody>(50);
    foreach (Pool<LandBody>.Node node in Bodies.AllNodes)
    {
        node.Item.Init(World);

        node.Item.BodyType = BodyType.Static;
        node.Item.Position = new Vector2(-9999999999, -9999999999);   //init offscreen

        PolygonShape box = new PolygonShape(1);                
        box.SetAsBox(2.5f, 2.5f, Vector2.Zero, 0);
        node.Item.CreateFixture(box);

        node.Item.FixtureList[0].Friction = 1000;
        node.Item.FixtureList[0].Restitution = 0;
        node.Item.FixtureList[0].CollisionGroup = -1;
    }
}

When you need to set a body, simply grab one from the pool, and set its position.

This may not be the proper way of handling this but it worked for me.

I took a animated gif to demonstrate how the bodies are swapped into position: enter image description here

\$\endgroup\$
  • \$\begingroup\$ Do you have the other code that goes with it? How do you know which ones you've used? Do you add and remove them each timestep? Thanks \$\endgroup\$ – jmasterx Jan 2 '14 at 19:20
  • \$\begingroup\$ The code is actually quite complex. All the blocks are stored in a Quadtree data structure. At each timestep, the Quadtree is queried in the general area where collidable objects exist. In the above animated gif, this collidable object is a box2d Body. If a block exists in this area, we move a body at its location. In the above screenshot, it is taken a step further, and the world "edge" is calculated, and bodies are only placed on Edge blocks. There is also a mechanism in place to return Bodies that are no longer needed after every update. \$\endgroup\$ – jgallant Jan 2 '14 at 19:27
  • \$\begingroup\$ Could you hint me to the calculation of the world edge? \$\endgroup\$ – jmasterx Jan 2 '14 at 20:13
  • \$\begingroup\$ The easiest implementation for this, is to store the Left/Right/Top/Bottom block neighbors inside each block object. Then, if any of the neighbors are blank, you have an edge tile. \$\endgroup\$ – jgallant Jan 2 '14 at 20:23
  • \$\begingroup\$ I have implemented this but I'm running into this issue gamedev.stackexchange.com/questions/68479/… How did you address that? \$\endgroup\$ – jmasterx Jan 7 '14 at 5:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.