私はAndengine/Box2D物理アドオンを使ってゲームを作っています。私はworld step計算中にbox2dボディの追加/移動/削除によってランダムなクラッシュを経験しました。そのため、setUserDataメソッドを使用してスプライト/ボディにフラグを立てるコードを実装しました。各ボディにJSONオブジェクトを付けてスプライトしますAndEngine Sprite/Box2Dボディー除去は、(必要に応じて)特定のボディーを削除しますが、スプライトのすべてのインスタンスを削除しますか?
が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();
}
私はコードを 'textureRegion.clone()'から 'textureRegion.deepCopy()'に変更したと思います。 S) – AndroidNoob
'textureRegion.deepCopy()'のように見えますが、このトリックは:)ポインタに感謝しました! – AndroidNoob
@AndroidNoob、よろしいですか? AndEngineライブラリを更新する必要があるようです。 =) – Egor