Android AndEngine: Simple Sprite Collision

I am new to AndEngine game development (or game development in general), and I am working on a very simple game. The setup is that I have 4 main sprites in the game:

a.) Fighter b) Tank c) Foot soldiers d) Bomb

The game is in an endless loop. The fighter exits on the left side, scales across the screen and continuously exits again every second. The tank exits on the left side of the screen, makes its way to the middle of the screen, lowers some infantrymen who are sent to the right side of the screen. Then the tank will look to the left and return to where it came from.

The player can tap the screen to launch a bomb that goes straight down. When it hits either a tank or a soldier, the bomb explodes (leaving an explosive sprite) and the bomb, as well as the object it collides with (the tank or soldier), breaks off the scene.

My dilemma is that I cannot solve the logic of the collision. I mean, I have functions, but I'm stupidly logical. Here is a snapshot of the game itself:

enter image description here

Here is my snippet (this function is called from the onCreateScene update handler:

protected void checkTankCollision() { // TODO Auto-generated method stub int numCompares = bombGroup.getChildCount(); for (int i = 0; i < numCompares; i++) { Sprite s = (Sprite) bombGroup.getChildByIndex(i); for (int j = 0; j < numCompares; j++) { Sprite s2 = (Sprite) tankGroup.getChildByIndex(j); if (s.collidesWith(s2)) { // boom AnimatedSprite boom = createExplosion(); boom.setPosition(s.getX(), s.getY()); getEngine().getScene().attachChild(boom); // WARNING: cannot detach from the list // while looping through the list final Sprite a = s; final Sprite b = s2; // this will do the action after the scene is done updating getEngine().getScene().postRunnable(new Runnable() { @Override public void run() { a.detachSelf(); b.detachSelf(); } }); } } } } 

The strength of the game closes after the launch of some bombs. It gives an indexOutOfBoundsException error.

Here is logCat:

  09-22 00:12:14.565: E/AndroidRuntime(924): FATAL EXCEPTION: UpdateThread 09-22 00:12:14.565: E/AndroidRuntime(924): java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1 09-22 00:12:14.565: E/AndroidRuntime(924): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251) 09-22 00:12:14.565: E/AndroidRuntime(924): at java.util.ArrayList.get(ArrayList.java:304) 09-22 00:12:14.565: E/AndroidRuntime(924): at org.andengine.entity.Entity.getChildByIndex(Entity.java:612) 09-22 00:12:14.565: E/AndroidRuntime(924): at com.cs119.bombthetank2.BombTankActivity.checkTankCollision(BombTankActivity.java:660) 09-22 00:12:14.565: E/AndroidRuntime(924): at com.cs119.bombthetank2.BombTankActivity$4.onUpdate(BombTankActivity.java:194) 09-22 00:12:14.565: E/AndroidRuntime(924): at org.andengine.engine.handler.UpdateHandlerList.onUpdate(UpdateHandlerList.java:47) 09-22 00:12:14.565: E/AndroidRuntime(924): at org.andengine.entity.Entity.onManagedUpdate(Entity.java:1395) 09-22 00:12:14.565: E/AndroidRuntime(924): at org.andengine.entity.scene.Scene.onManagedUpdate(Scene.java:284) 09-22 00:12:14.565: E/AndroidRuntime(924): at org.andengine.entity.Entity.onUpdate(Entity.java:1167) 09-22 00:12:14.565: E/AndroidRuntime(924): at org.andengine.engine.Engine.onUpdateScene(Engine.java:591) 09-22 00:12:14.565: E/AndroidRuntime(924): at org.andengine.engine.Engine.onUpdate(Engine.java:586) 09-22 00:12:14.565: E/AndroidRuntime(924): at org.andengine.engine.Engine.onTickUpdate(Engine.java:548) 09-22 00:12:14.565: E/AndroidRuntime(924): at org.andengine.engine.Engine$UpdateThread.run(Engine.java:820) 

Entity and Scene actions are part of AndEngine, and there really cannot be an error. BombTheTank2 is the name of my activity, so yes, there is a mistake.

+1
source share
2 answers

You seem to separate the sprites before stopping repeating through the list of children. Let them do it in a clean way. Try the following:

 protected void checkTankCollision() { int numCompares = bombGroup.getChildCount(); final ArrayList<Sprite> toBeDetached = new ArrayList<Sprite>(); for (int i = 0; i < numCompares; i++) { Sprite s = (Sprite) bombGroup.getChildByIndex(i); for (int j = 0; j < numCompares; j++) { Sprite s2 = (Sprite) tankGroup.getChildByIndex(j); if (s.collidesWith(s2)) { // boom AnimatedSprite boom = createExplosion(); boom.setPosition(s.getX(), s.getY()); getEngine().getScene().attachChild(boom); // 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(); } toBeDetached.clear(); } }); } 

EDIT: The real problem was somewhere else - Erasmus accidentally repeated the group of Tanks as many times as they did over the group of bombs. The solution was to check the number of tanks and stop the iteration earlier.

I personally always use For-Every loops, if I really don't need to know the index, it saved me a lot of headaches :-)

+2
source

I think you need to do a "detach" from UpdateThread, so instead

  getEngine().getScene().postRunnable(new Runnable() { @Override public void run() { a.detachSelf(); b.detachSelf(); } 

try it

 runOnUpdateThread(new Runnable() { @Override public void run() { a.detachSelf(); b.detachSelf(); } 

every time you disconnect something, you must decrease the numCompares value. After you separate something, the array that contains these objects is now smaller. Since you are pulling the length of the array at the beginning, you are eventually running after the end of the array - thus your IndexOutOfBounds error. Cancellation still needs to be done on UpdateThread.

+1
source

Source: https://habr.com/ru/post/925975/


All Articles