AndEngine - удаление определенного спрайта и его тела - PullRequest
3 голосов
/ 02 марта 2012

Я хотел бы удалить тело при нажатии на элемент. Как вы видите, я настроил его как настенное крепление.

Когда по элементу щелкают, спрайт удаляется, теперь я просто хотел бы также удалить тело ..

public void addSprites(Scene scene, int x,int y,int width,int height,String type,Body body){
    Sprite sprite = null;

    if(type.equals(TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_WOOD)) {
        sprite = new Sprite(x, y, width, height, this.wood, this.getVertexBufferObjectManager()){
            @Override
            public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
                mScene.detachChild(this);
                mPhysicsWorld.destroyBody(woodBody);
                return true;
            }

        };
           final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(0, 0.5f, 0.5f);
          woodBody =  PhysicsFactory.createBoxBody(this.mPhysicsWorld, sprite, BodyType.StaticBody, wallFixtureDef);
             mScene.registerTouchArea(sprite);
        Log.e("TYPE", "Wood");
    }
    scene.attachChild(sprite);
            }

Что я хочу сделать, так это то, что при нажатии на элемент я хочу удалить спрайт и тело, к которому он прикреплен. У меня работает код, но единственная проблема в том, что он удаляет ВСЕ тела, я использую метод, чтобы прикрепить элементы к уровню, таким образом, это всего 3 элемента, и при нажатии на одно тело тело удаляется из ВСЕХ спрайтов. , когда это должен быть только тот, кто нажал.

Кто-нибудь знает, как это сделать?

Ответы [ 2 ]

8 голосов
/ 03 марта 2012

Я не уверен, но, вероятно, это происходит, потому что вы используете одну и ту же переменную для всех тел

woodBody =  PhysicsFactory.createBoxBody(this.mPhysicsWorld, sprite, BodyType.StaticBody, wallFixtureDef);

Чтобы установить хорошую связь между телом и спрайтом, я предлагаю вам расширить Sprite и объявить переменную тела внутри вашего класса. Например, я делаю это таким образом

public class Ball extends Sprite{

final FixtureDef ballFixtureDef = PhysicsFactory.createFixtureDef(1.0f, 0.0f, 0.0f, false, Main.CATEGORYBIT_BALL, Main.MASKBITS_BALL, (short)0);

Body body;
float velocityX, velocityY; 
int type;   

public Ball(float pX, float pY, TextureRegion pTextureRegion, PhysicsWorld pWorld, float velocityX, float velocityY, int type) 
{
    super(pX, pY, pTextureRegion);
    this.type = type;
    this.velocityX = velocityX;
    this.velocityY = velocityY;
    body = PhysicsFactory.createCircleBody(pWorld, this, BodyType.DynamicBody, ballFixtureDef);
    body.setUserData(Ball.this);
    pWorld.registerPhysicsConnector(new PhysicsConnector(this, body, true, true));
}
}

и способ уничтожения спрайта с телом

private void destroyBall(final Ball ball)
    {
        this.runOnUpdateThread(new Runnable(){

            @Override
            public void run() {

                final Body body = ball.body;
                mPhysicsWorld.unregisterPhysicsConnector(mPhysicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape(ball));
                mPhysicsWorld.destroyBody(body);
                mScene.detachChild(ball);
                ballsList.remove(ball);
            }});

    }

и вы просто создаете объект таким образом

Ball b = new Ball(float pX, float pY, TextureRegion pTextureRegion, PhysicsWorld pWorld, float velocityX, float velocityY, int type) 
{
    @Override
    public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY)
    {
        destroyBall(this);
    }
}
2 голосов
/ 02 марта 2012

Я не совсем уверен, но я думаю, что вам нужно пометить элементы или объекты, которые должны быть удалены в первую очередь. Затем, когда игра обновляется, она должна пройти через все объекты и проверить, какие из них помечены, а затем удалить их. Я тоже новичок в этом, но здесь ничего не говорится:

Итак, хороший способ сделать это в AndEngine - это сначала сделать IUpdateHandler следующим образом:

/**
* This wil get called every frame and is placed inside of your
* main game activity or where ever you want.
**/
public IUpdateHandler getCollisionUpdateHandler(){

    return new IUpdateHandler(){

         @Override
         public void onUpdate(float pSecondsElapsed) {

             // loop through all of your sprites
             for(int i=0; i<GameActivity.this.spriteList.length; i++) {

                  //if sprite is flagged for deletion, begin removal
                  if( GameActivity.this.spriteList.get(i).isDelete()){
                       // get the next sprite to delete
                       final mSprite Object = GameActivity.this.spriteList.get(i);
                       // can remove it from the list now
                       Game.this.spriteList.remove(i); 

                       final Scene scene = GameActivity.this.mEngine.getScene();
                       final Body body = GameActivity.this.mPhysicsWorld.getPhysicsConnectorManager().findBodyByShape(Object);
                       mPhysicsWorld.destroyBody(body);
                       //scene.getLayer(0).removeEntity(Object);
                       //scene.getLayer(1).removeEntity(Object);
                       scene.detachChild( Object );
                  }
               }
           }
      }
 }

Тогда просто зарегистрируйте этот обработчик обновлений. Вот так:

mScene.registerUpdateHandler( this.getCollisionUpdateHandler() );

Так что теперь, когда вы хотите удалить спрайт (когда он нажат), вы просто меняете свой метод на:

@Override
public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float  pTouchAreaLocalX, final float pTouchAreaLocalY) {
    MainActivity.spriteList.add( this );
    this.delete = true;
    return true;
}

Надеюсь, это поможет. Вот откуда я это взял: (Я просто попытался сделать так, чтобы она соответствовала вашей проблеме :))

www.andengine.org / forums / tutorials / box2d-collision-and-removal-t523.html

...