AndEngine Sprite/Box2D Body removal removes a particluar body (as it should), but removes all instances of the sprite?

StackOverflow https://stackoverflow.com/questions/7359787

Question

I am making a game using Andengine/Box2D physics addon. I experienced the random crashes due to the addition/movement/deletion of box2d bodies during the world step calculation, so I have implemented code to flag sprites/bodies for removal using the setUserData method - I attach a JSON object to each body and sprite that contains the type of sprite, the body, and the sprite itself and its delete status:

private JSONObject makeUserData(int type, Body body, Object sprite)
{
    JSONObject myObject = new JSONObject();

    try {
        myObject.put("type", type);
        myObject.put("sprite", sprite);
        myObject.put("body", body);
        myObject.put("deleteStatus", false);
    } catch (JSONException e) {
        Log.d(TAG,"Exception creating user data:"+e);
    }
    return myObject;
}

then in an update thread iterate through all the bodies in my world looking for these flags and delete the sprites/bodies with the flag. The bodies remove correctly, however the sprite removal seems to delete every instance of that particluar sprite rather than just removing the particular one i flagged to remove! I can tell the bodies are still present without the sprite as my player collides with invisible objects! Here is the code for removal:

 private void removeObjectsSetForDestruction()
{
    if(this.mPhysicsWorld!=null)
    {
        Iterator<Body> allMyBodies = this.mPhysicsWorld.getBodies();
        boolean isDelete = false;
        JSONObject currentBodyData;
        while(allMyBodies.hasNext())
        {
             try {
                 currentBodyData = (JSONObject)allMyBodies.next().getUserData();
                 if(currentBodyData!=null)
                 {
                     isDelete = (Boolean) currentBodyData.get("deleteStatus");
                    if(isDelete)
                    {
                        destroyObstruction((Body) currentBodyData.get("body"));
                    }
                 }
            } catch (JSONException e) {
                Log.d(TAG,"Error getting world bodies data:"+e);
            }
        }
    }
}

private void destroyObstruction(Body obstructionBody) throws JSONException
{
    obstructionBody.setActive(false);

        JSONObject secondBodyData = null;
        if(obstructionBody.getUserData()!=null)
        {
            secondBodyData=(JSONObject) obstructionBody.getUserData();

            //explodeObstruction(((IEntity) secondBodyData.get("sprite")).getX(),((IEntity) secondBodyData.get("sprite")).getY());
            if(secondBodyData.get("sprite") instanceof AnimatedSprite)
            {
                removeObject((AnimatedSprite) secondBodyData.get("sprite"));
            }
            else
            {
                removeObject((Sprite) secondBodyData.get("sprite"));
            }
        }


}

private void removeObject(final AnimatedSprite myAnimSprite)
{
    final PhysicsConnector myPhysicsConnector = this.mPhysicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape(myAnimSprite);

    this.mPhysicsWorld.unregisterPhysicsConnector(myPhysicsConnector);
    this.mPhysicsWorld.destroyBody(myPhysicsConnector.getBody());

    this.mScene.unregisterTouchArea(myAnimSprite);
    this.mScene.detachChild(myAnimSprite);

    System.gc();
}

private void removeObject(final Sprite mySprite)
{
    final PhysicsConnector myPhysicsConnector = this.mPhysicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape(mySprite);

    this.mPhysicsWorld.unregisterPhysicsConnector(myPhysicsConnector);
    this.mPhysicsWorld.destroyBody(myPhysicsConnector.getBody());

    this.mScene.unregisterTouchArea(mySprite);
    this.mScene.detachChild(mySprite);

    System.gc();
}
Was it helpful?

Solution

I would like to take a look at your objects creating code. I assume every sprite has the same TextureRegion used, so when the region of one sprite is being changed - same regions on other sprites are being changed too due to Android architecture specifics. For every sprite with same TextureRegion you should use textureRegion.clone() as the last parameter of the constructor. Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top