AndEngine Sprite/Box2D 主体移除会移除特定的主体(理应如此),但会移除该精灵的所有实例?

发布于 2024-12-03 11:48:23 字数 3194 浏览 0 评论 0原文

我正在使用 Andengine/Box2D 物理插件制作游戏。由于在世界步骤计算期间添加/移动/删除 box2d 主体,我经历了随机崩溃,因此我实现了代码来使用 setUserData 方法标记要删除的精灵/主体 - 我将一个 JSON 对象附加到每个主体和精灵包含精灵的类型、主体、精灵本身及其删除状态:

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;
}

然后在更新线程中迭代我的世界中的所有主体,查找这些标志并删除带有该标志的精灵/主体。主体正确删除,但是精灵删除似乎删除了该特定精灵的每个实例,而不是仅删除我标记要删除的特定精灵!当我的玩家与不可见的物体碰撞时,我可以看出没有精灵的尸体仍然存在!这是删除的代码:

 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();
}

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();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

动听の歌 2024-12-10 11:48:23

我想看看您的对象创建代码。我假设每个 sprite 都使用相同的 TextureRegion,因此当一个 sprite 的区域发生更改时,由于 Android 架构的具体情况,其他 sprite 上的相同区域也会发生更改。对于具有相同 TextureRegion 的每个精灵,您应该使用 textureRegion.clone() 作为构造函数的最后一个参数。希望这有帮助。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文