Search code examples
c++cocos2d-xgame-physicstile

How to create a PhysicsBody for each tile on a TileMap? (cocos2d-x)


I'm currently trying to combine the inbuilt PhysicsBody and TileMap classes in cocos2d-x to create the levels (walls) for my physics-based sidescroller. I have maps of size 80*24 tiles and each tile is 30*30 pixels big - I need to assign a static box shaped physics body to each tile.

for    (int x=0; x < 80; x++)       //width of map
    {
        for (int y = 0; y < 24; y++)   //height of map
        {
            auto spriteTile = wallLayer->getTileAt(Vec2(x,y));
            if (spriteTile != NULL)    
            {
                PhysicsBody* tilePhysics = PhysicsBody::createBox(Size(30.0f, 30.0f), PhysicsMaterial(1.0f, 1.0f, 0.0f));                 
                tilePhysics->setDynamic(false);   //static is good enough for walls
                spriteTile->setPhysicsBody(tilePhysics);
            }
        }
    } 

The above code works, but is very slow and brings performance down from 60 fps to around 20. Is there a less brute-force approach, which can more efficiently create the physics bodies? Note: most the map is blank, so I dont think the number of bodies/tiles is the main problem.

Any insight would be helpful, thanks


Solution

  • First, check whether debug draw is on for physics, as it can reduce FPS considerably. Also, make sure you're measuring FPS on the device and not on the simulator, as it's not reliable there.

    If that doesn't help, then you'll have to employ some method of contour tracing to avoid creating a static body for each tile in your tile map. It's better to create 1 static body for each contour that you trace out of the tile map. That way, you will end up with much fewer physics bodies and your performance won't be hurt that much.

    One method of doing it is the so called marching squares algorithm. Another one is Moore neighborhood algorithm.