0

I don't know what I'm missing... the full code is pretty big so I'll just put the part throwing exceptions here.

 for (int i = 0; i < player.getBullets().size(); i++) { //for every player bullet for (int j = 0; j < aliens.getAliens().size(); j++) { //for every player bullet every alien player.getBullets().get(i); aliens.getAliens().get(j); if (player.getBullets().get(i).getBounds().intersects(aliens.getAliens().get(j).getBounds())){ //player bullet vs alien collison if (aliens.getAliens().get(j).getType() == 1) score += 2 + level; else if(aliens.getAliens().get(j).getType() == 2) score += 4 + level; else score += 8 + level*2; aliens.getAliens().remove(j); // alien dies player.getBullets().remove(i); System.out.println("player bullet removed"); } } } 

It threw an exception on the //player bullet vs alien collision line. I added in player.getBullets().get(i) and the getAliens() to figure which one threw the exception and it was the player one.

Error seems kind of random, but I believe it goes out of bounds when an alien moves sideways onto a bullet. It works fine if the bullet hits the alien straight on. Could this be an error with using intersects?

By the way, this is a Space Invaders mimic. Any help would be appreciated.

2
  • 3
    Please post the exception or at least tell at which line it occurs Commented Nov 30, 2011 at 19:19
  • Does this answer your question? ArrayList index out of bounds Commented Oct 3, 2022 at 4:22

7 Answers 7

3

Use Iterator which supports remove operation on it's collection. To give you an idea (all irrelevant code from OP removed):

 List<Bullet> bullets = new ArrayList<Bullet>(); List<Alien> aliens = new ArrayList<Alien>(); Iterator<Alien> alienIterator = aliens.iterator(); Iterator<Bullet> bulletIterator = bullets.iterator(); while (bulletIterator.hasNext()) { //for every player bullet while (alienIterator.hasNext()) { //for every player bullet every alien Bullet bullet = bulletIterator.next(); Alien alien = alienIterator.next(); if (bullet.getBounds().intersects(alien.getBounds())) { //player bullet vs alien collison bulletIterator.remove(); alienIterator.remove(); System.out.println("player bullet removed"); } } } 

Note that it's still susceptible to IllegalStateException if you modify aliens/bullets somewhere else concurrently.

Sign up to request clarification or add additional context in comments.

Comments

2

You're altering your lists as you're traversing them (by calling .remove() inside the loop). You're deleting the bullet in the middle of checking for collisions with it.

One solution is to give aliens/bullets/other such objects an isDead variable. Then, instead of deleting them inside the loop, wait until after the loop and delete everyone with isDead == true.

Comments

1

The problem is that you are removing items from an array you are traversing. According to the Javadoc:

int size() Returns the number of elements in this collection. 

This is yielding a number which, when you remove items from the collection, will be larger than the actual collection size, hence resulting into an out of bounds.

You need to use an iterator to traverse the collections and then use the iterator.remove() to remove items from a collection while you are traversing it.

Comments

1

You should create iterators to iterate over the players and aliens. Then when one should be removed do that on the iterator instead of the original list. That makes the looping works.

As @Toomai suggest, instead of removing, flag them as dead, possibly delete them later, is also a nice solution.

Comments

1

Let's say that player 0 is killed. When you remove his bullet, all the other bullets move down one in index. So when the index increments to 1, you will be looking at what was originally bullet 2, not bullet 1.

When removing from a List by index, always go through the loops in reverse order, so that you do not affect the order of elements still to be looked at.

However, the problem you see (the kapow) happens if the last bullet kills anything. While you are still in the for (j) loop, you remove the last bullet. The next call to getBullet(i) will fail because there is no longer a bullet i, there are now only i-1. When a bullet kills something, you should break out of the inner loop. (Assuming a bullet can;t kill 2 aliens at once)

That said, you would be much better served by

  1. Using the new style for looping, for (Bullet bullet : player.getBullets() {} It will really really simplify your code!!!
  2. Consider not deleting on the fly. Collect everything to be deleted into two temporary lists, deadAliens and usedBullets. At the end of your loop call

    aliens.getAliens().removeAll(deadAliens ); player.getBullets().removeAll(deadBullets);

Comments

0

In your code, you are removing items from what i guess is a list

 aliens.getAliens().remove(j); // alien dies player.getBullets().remove(i) 

What might happen is that you are still looping in the inner loop while the condition of the outer loop is not valid.

Comments

0

Looks to me that player.getBullets().remove(i); removes something but you continue to loop. You have to break out of the inner for loop after System.out.println...

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.