Android AndEngine:正确处理Collission Detection

我正在研究一个涉及ff的简单AndEngine游戏.精灵

a.)坦克
b.)士兵
c.)炸弹

在这里一个类似的问题:Android AndEngine: Simple sprite collision

游戏的样子:

但是,在解决最初的问题时,又出现了另一个问题:

当炸弹(飞机当前所在的地方并垂直下降,直到它到达目标或地板,通过鼠标点击)击中目标,说一名士兵,士兵精灵必须分离并留下血液飞溅精灵1秒,以及炸弹爆炸精灵.但是,游戏力关闭会产生indexOutOfBoundError.据我所知,这可能是炸弹与其目标之间精灵数量的差异,导致出现数组错误,但logCat根本没有帮助.

09-22 11:13:37.585: E/AndroidRuntime(735): FATAL EXCEPTION: UpdateThread
09-22 11:13:37.585: E/AndroidRuntime(735): java.lang.indexoutofboundsexception: Invalid  index 5,size is 5
09-22 11:13:37.585: E/AndroidRuntime(735):  at java.util.ArrayList.throwindexoutofboundsexception(ArrayList.java:251)
09-22 11:13:37.585: E/AndroidRuntime(735):  at java.util.ArrayList.get(ArrayList.java:304)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.entity.Entity.onManagedUpdate(Entity.java:1402)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.entity.Entity.onUpdate(Entity.java:1167)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.entity.Entity.onManagedUpdate(Entity.java:1402)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.entity.scene.Scene.onManagedUpdate(Scene.java:284)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.entity.Entity.onUpdate(Entity.java:1167)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.engine.Engine.onUpdateScene(Engine.java:591)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.engine.Engine.onUpdate(Engine.java:586)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.engine.Engine.onTickUpdate(Engine.java:548)
09-22 11:13:37.585: E/AndroidRuntime(735):  at org.andengine.engine.Engine$UpdateThread.run(Engine.java:820)

如此处所示,logCat没有在我的代码上给出错误,但是在AndEngine本身上,并且很可能不是这样.

我的新代码在onCreateScene Update Handler中运行(根据上面链接的上一个问题的帮助):

protected void checkSoldierCollision() {
    // Todo Auto-generated method stub

    int numBombs = bombGroup.getChildCount();
    int numTroops = troopsGroup.getChildCount();
    final ArrayList<Sprite> tobedetached = new ArrayList<Sprite>();
    for (int i = 0; i < numBombs; i++) {
        Sprite s = (Sprite) bombGroup.getChildByIndex(i);
        for (int j = 0; j < numTroops; j++) {
            Sprite s2 = (Sprite) troopsGroup.getChildByIndex(j);

            if (s.collidesWith(s2)) {

                /*Sprite splat = createSplat();
                splat.setPosition(s.getX(),s.getY());
                getEngine().getScene().attachChild(splat);*/

                Sprite splode = createExplosion();
                splode.setPosition(s.getX(),s.getY());
                getEngine().getScene().attachChild(splode);

                // WARNING: cannot detach from the list
                 //while looping through the list
                tobedetached.add(s);
                tobedetached.add(s2);

            }
        }
    }
    runOnUpdateThread(new Runnable() {
        @Override
        public void run() {
            for (Sprite s : tobedetached) {
                s.detachSelf();
                Sprite splode = createExplosion();
                splode.setPosition(s.getX(),s.getY());
                getEngine().getScene().attachChild(splode);

            }
            tobedetached.clear();
        }
    });

}

我注意到它只能是一个splat或爆炸,因为它没有错误.如果在碰撞时溅射和爆炸都填充场景,则会发生错误.

此外,即使炸弹不击中士兵(但仍然分开并在击中地板时被爆炸云取代),它也会出现类似的错误

我的createBomb函数

public Sprite createBomb(float x,float y) {
    Sprite bombSprite = new Sprite(x,y,this.mBombTextureRegion,getVertexBufferObjectManager());

    MoveYModifier downModBomb = new MoveYModifier(1,60,FLOOR);

    downModBomb.addModifierListener(new IModifierListener<IEntity>() {

        @Override
        public void onModifierStarted(IModifier<IEntity> pModifier,IEntity pItem) {

        }

        @Override
        public void onModifierFinished(IModifier<IEntity> pModifier,final IEntity pItem) {
             pItem.detachSelf();
             AnimatedSprite explodeSprite = createExplosion();
             explodeSprite.setPosition(pItem.getX(),FLOOR);
             getEngine().getScene().attachChild(explodeSprite);
        }
    });

    bombSprite.registerEntityModifier(downModBomb); // register action
    return bombSprite;
}

我的onCreateScene炸弹功能和碰撞up​​dateHandler:

scene.setonScenetouchListener(new IOnScenetouchListener() {

        @Override
        public boolean onScenetouchEvent(Scene pScene,TouchEvent pScenetouchEvent) {
            if (pScenetouchEvent.getAction() == TouchEvent.ACTION_UP) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Sprite bomb = createBomb(f16Sprite.getX(),f16Sprite.getY());
                        bombGroup.attachChild(bomb);
                    }
                });

                return true;
            }
            return false;
        }
    });

    // periodic checks
    scene.registerUpdateHandler(new IUpdateHandler() {

        @Override
        public void onUpdate(float pSecondsElapsed) {
            // checkTankCollision();
            // checkSoldierBackCollision();
            checkSoldierCollision();
        }

        @Override
        public void reset() {
        }
    });

我的createExplosion方法

public AnimatedSprite createExplosion() {
    AnimatedSprite boomSprite = new AnimatedSprite(0,this.mExplodeTextureRegion,getVertexBufferObjectManager());

    DelayModifier delay = new DelayModifier(.3f); // delay in seconds,can
                                                    // take float numbers .5
                                                    // seconds
    delay.addModifierListener(new IModifierListener<IEntity>() {

        @Override
        public void onModifierStarted(IModifier<IEntity> pModifier,IEntity pItem) {
            ((AnimatedSprite) pItem).animate(new long[] { 100,100,100 },// durations/frame
                    new int[] { 1,2,3 },// which frames
                    true); // loop
        }

        @Override
        public void onModifierFinished(IModifier<IEntity> pModifier,final IEntity pItem) {
            ((AnimatedSprite) pItem).detachSelf();
        }
    });

    boomSprite.registerEntityModifier(delay); // register action
    return boomSprite;
}

我该如何解决这个问题?循环逻辑并不完全是我的强项.我也对如何实现这个问题持开放态度.

更新:刚刚意识到,即使碰撞的结果是啪啪声或爆炸声,也没关系,如果玩家持续发送垃圾邮件(比如4-5次)整个游戏部队关闭.

– 无论何时创建焊料/罐的实例,似乎都有可允许的轰炸次数.每当炸弹袭击一名士兵时,我就会先关闭制造爆炸(所以血液板只会留在原位而不是两者).它工作正常,但超过4-6枚炸弹,游戏结束.当一个新的士兵实例产生时(意味着当旧的士兵离开屏幕并分离时),然后在游戏部队关闭之前给予玩家4-6个炸弹.

解决方法

问题可能是由于您通过调用runOnUiThread在UI线程上附加炸弹而检查更新线程上的冲突.尝试在runOnUpdateThread中添加炸弹.

通常,您希望保持一致的用于操作事物的线程,否则将出现奇怪的错误,这是调试的痛苦.

旁注:UI线程非常适合显示Toasts,请参阅此示例:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(GameActivity.this,"Hello!",Toast.LENGTH_SHORT).show();
    }
});

相关文章

这篇“android轻量级无侵入式管理数据库自动升级组件怎么实现...
今天小编给大家分享一下Android实现自定义圆形进度条的常用方...
这篇文章主要讲解了“Android如何解决字符对齐问题”,文中的...
这篇文章主要介绍“Android岛屿数量算法怎么使用”的相关知识...
本篇内容主要讲解“Android如何开发MQTT协议的模型及通信”,...
本文小编为大家详细介绍“Android数据压缩的方法是什么”,内...