title: Android AndEngine: handling Collission Detection properly
body: <p>I am working on a simple AndEngine game that involves the ff. sprites </p>
  
  <p>a.) tanks
  b.) soldiers
  c.) bombs</p>
  
  <p>I have a similar question located here: <a href="https://stackoverflow.com/questions/12532918/android-andengine-simple-sprite-collision">Android AndEngine: Simple sprite collision</a></p>
  
  <p>What the game looks like:</p>
  
  <p><img src="https://i.stack.imgur.com/7TayY.jpg" alt="enter image description here"></p>
  
  <p>However upon fixing the initial problem, another problem arose:</p>
  
  <p>When the bomb (spawns where the plane is currently at and goes down vertically until it reaches a target or floor, by means of mouse click) hits a target, say a soldier, the soldier sprite must detach and leave behind it a blood splatter sprite for 1 second, as well as an explosion sprite from the bomb. However, the game force closes giving an indexOutOfBoundError. I understand that this might probably be a discrepancy of sprite count between the bomb and its target causing an out of bound array error, but logCat isn't helping at all. </p>
  
  <pre><code>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)
  </code></pre>
  
  <p>As seen here, logCat isn't giving an error on my code, but on the AndEngine itself, and that's most probably not the case.</p>
  
  <p>My new code that runs in the onCreateScene Update Handler (as per help with the linked previous problem above):</p>
  
  <pre><code>protected void checkSoldierCollision() {
      // TODO Auto-generated method stub
  
      int numBombs = bombGroup.getChildCount();
      int numTroops = troopsGroup.getChildCount();
      final ArrayList&lt;Sprite&gt; toBeDetached = new ArrayList&lt;Sprite&gt;();
      for (int i = 0; i &lt; numBombs; i++) {
          Sprite s = (Sprite) bombGroup.getChildByIndex(i);
          for (int j = 0; j &lt; 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();
          }
      });
  
  }
  </code></pre>
  
  <p>What I noticed that it can only be either a splat or an explosion for it not to have an error. If both splat and explosion were to populate the scene upon collision, an error occurs.</p>
  
  <p>Also, even if the bombs dont hit the soldiers (but still detaching and replaced with an explosion cloud when hitting the floor) it also gives a similar error:</p>
  
  <p>My createBomb function:</p>
  
  <pre><code>    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&lt;IEntity&gt;() {
  
          @Override
          public void onModifierStarted(IModifier&lt;IEntity&gt; pModifier,
                  IEntity pItem) {
  
          }
  
          @Override
          public void onModifierFinished(IModifier&lt;IEntity&gt; 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;
  }
  </code></pre>
  
  <p>My onCreateScene bomb function and collision updateHandler:</p>
  
  <pre><code>    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() {
          }
      });
  </code></pre>
  
  <p>My createExplosion method:</p>
  
  <pre><code>            public AnimatedSprite createExplosion() {
      AnimatedSprite boomSprite = new AnimatedSprite(0, 0,
              this.mExplodeTextureRegion, getVertexBufferObjectManager());
  
      DelayModifier delay = new DelayModifier(.3f); // delay in seconds, can
                                                      // take float numbers .5
                                                      // seconds
      delay.addModifierListener(new IModifierListener&lt;IEntity&gt;() {
  
          @Override
          public void onModifierStarted(IModifier&lt;IEntity&gt; 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&lt;IEntity&gt; pModifier,
                  final IEntity pItem) {
              ((AnimatedSprite) pItem).detachSelf();
          }
      });
  
      boomSprite.registerEntityModifier(delay); // register action
      return boomSprite;
  }
  </code></pre>
  
  <p>How do I remedy this? Looping logic isn't entirely my strong point. I am also open on how to implement this alternatively.</p>
  
  <p>UPDATE: Just realized that even if the result of the collision is either splat or explosion, it doesn't matter, if the player keeps spamming bombs (like say 4-5 times) the entire game force closes.</p>
  
  <p>-It seems that there is an allowable number of bombing whenever an instance of a solder/tank is created. I have turned off the create explosion first whenever a bomb hits a soldier (so a bloodsplat would just remain in its place instead of both). It works ok, but exceed 4-6 bombs and the game closes. When a new soldier instance spawns (meaning when the old ones go off screen and detaches) the player is then given 4-6 bombs before the game force closes.</p>