[英]Removing Box2D bodies crashes AndEngine
在此先感謝您的幫助!
我正在構建一個打磚塊/突圍風格的游戲,並且由於身體移除而遇到一些問題(至少這是我懷疑問題所在)。 當我運行游戲時,大部分時間一切正常,但游戲時不時會崩潰。 在這次崩潰期間,所有附着在身體上的精靈都會消失,任何沒有身體的精靈都會留在屏幕上。 沒有 LogCat 錯誤,但 FPS 急劇下降。 此外,我注意到有時在觸發聯系人偵聽器中的代碼之前聯系人注冊兩次(您可以在下面的 ContactListener 中看到我在何處實現日志文件輸出)。
在游戲中,我使用螺栓代替磚塊,下面列出了我用來生成螺栓的代碼。 之后,我將展示我如何使用 ContactListener,然后我給出了移除 body/sprite 組合的代碼。 非常感謝任何幫助或建議!
謝謝,
亞當
創建在接觸時將被刪除的主體/精靈項目。
//BOLTS
final FixtureDef boltFixtureDef = PhysicsFactory.createFixtureDef(1, 1.0f, 0.1f);
final Body[] boltBody=new Body[BOLT_NUMBER];
final Sprite[] boltSprite=new Sprite[BOLT_NUMBER];
final PhysicsConnector[] facePhysicsConnector= new PhysicsConnector[BOLT_NUMBER];
String[] bodyNames=new String[BOLT_NUMBER];
for(int i=0; i<BOLT_NUMBER; i++){
boltSprite[i] = new Sprite(-100,-100, sceneManager.mBolt, sceneManager.activity.getVertexBufferObjectManager());
boltSprite[i].setCullingEnabled(true);
boltBody[i] = PhysicsFactory.createBoxBody(mPhysicsWorld, boltSprite[i], BodyType.KinematicBody, boltFixtureDef);
mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(boltSprite[i], boltBody[i], true, true));
bodyNames[i]="bolt"+Integer.toString(i);
boltBody[i].setUserData(bodyNames[i]);
facePhysicsConnector[i] = mPhysicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape(boltSprite[i]);
boltBody[i].setTransform(xLocations[i]/PMR, yLocations[i]/PMR, 0);}
for(int i=0; i<BOLT_NUMBER; i++){
scene.attachChild(boltSprite[i]);}
聯系人監聽器:
final ContactListener contact = new ContactListener(){
@Override
public void postSolve(Contact contact, ContactImpulse impulse) {
String a = (String) contact.getFixtureA().getBody().getUserData();
String b = (String) contact.getFixtureB().getBody().getUserData();
if(a != null && b != null) {
for(int i=0; i<BOLT_NUMBER; i++){
if(a.equals("wrench") && b.equals(facePhysicsConnector[i].getBody().getUserData()) ||
a.equals(facePhysicsConnector[i].getBody().getUserData()) && b.equals("wrench")) {
//boltCollision[i]=true;
Log.i("contact","bolt contact" + i);
myDestroyer(facePhysicsConnector[i], true);
Log.i("contact","bolt POSTcontact" + i);}
else if((a.equals("wrench") && b.equals("paddle")) ||
(a.equals("paddle") && b.equals("wrench"))) {
Log.i("contact","paddle contact");
SpringNoise=true;}
else if((a.equals("wrench") && b.equals("door")) ||
(a.equals("door") && b.equals("wrench"))) {
Log.i("contact","door contact");
WoodNoise=true;}
}}
}
@Override
public void endContact(final Contact contact) {}
@Override
public void beginContact(Contact contact) {}
@Override
public void preSolve(Contact contact, Manifold oldManifold) {}
};
這是刪除身體/精靈組合的代碼:
private void myDestroyer(final PhysicsConnector facePhysicsConnector2, final Boolean bodyToo){
if(killingInProcess == false){
killingInProcess = true;
//final PhysicsConnector facePhysicsConnector2 = mPhysicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape(myShape);
sceneValue.engine.registerUpdateHandler(new IUpdateHandler(){
@Override
public void onUpdate(float pSecondsElapsed) {
sceneValue.engine.unregisterUpdateHandler(this);
sceneValue.engine.runOnUpdateThread(new Runnable(){
@Override
public void run() {
Log.i("contact","removing bolt");
mPhysicsWorld.unregisterPhysicsConnector(facePhysicsConnector2);
Vibrator v = (Vibrator) sceneValue.activity.getSystemService(Context.VIBRATOR_SERVICE);
//myFixture.getBody().destroyFixture(myFixture);
if(bodyToo == true){
mPhysicsWorld.destroyBody(facePhysicsConnector2.getBody());
}
facePhysicsConnector2.getShape().registerEntityModifier(new ParallelEntityModifier(new RotationModifier(3,180,0),
new ScaleModifier(3, 1, 0)));
sceneValue.mBlockSound.play();
v.vibrate(75);
//mScene.detachChild(mySprite);
System.gc();
killingInProcess = false;
}
});
}
@Override
public void reset() {
}
});
}}
我不確定崩潰問題,但我知道為什么移除屍體太晚了。
該方法postSolve
從UpdaeThread調用。 但是不是在那里刪除主體,而是注冊另一個更新處理程序(因此它的代碼在下一次游戲更新中運行)。 在此代碼中,您在runOnUpdateThread
運行另一個代碼,以便它在下一次游戲更新中再次運行。 您無緣無故跳過了 2 個更新:) 這可能會產生問題(可能會)
我建議你解決這個問題,這會尋找另一個問題(這可能很嚴重,很容易解決)
我不確定,但我認為問題可能在於您刪除了精靈。 我遇到了這個問題,現在我試圖在這樣的更新處理程序中殺死主體(IUpdateHandler 中的 onUpdate 方法):
final PhysicsConnector physicsConnector = physicsWorld
.getPhysicsConnectorManager().findPhysicsConnectorByShape(
body);
body.clearEntityModifiers();
physicsWorld.unregisterPhysicsConnector(physicsConnector );
physicsWorld.destroyBody(physicsConnector.getBody());
scene.detachChild(body);
activity.getEngine().unregisterUpdateHandler(this);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.