IndexOutOfBounds index: 7 size: 7 [SOLVED]

Hello Everyone,

Recently i have been making a game and i have encountered a problem. I have an IndexOutOfBounds Exception but i cant seem to fix it.
I am basically trying to remove a bullet once it hits the enemy. It works for one enemy but not for the rest. here is the code i used could you please help me thanks :slight_smile:

package com.glennbrann.Controllers;

import java.awt.Graphics;
import java.util.ArrayList;

import com.glennbrann.Game.Game;
import com.glennbrann.Screen.Sprites;
import com.glennbrann.Stuff.Bullet;
import com.glennbrann.Stuff.Enemy;

public class BulletController {
	ArrayList<Enemy> e = new ArrayList<Enemy>();
	ArrayList<Bullet> b = new ArrayList<Bullet>();

	
	Bullet bullet;
	Bullet bullets;
	
	Game game;
	Sprites sprites;
	Enemy enemy;
	
	
	public BulletController(Game game, Sprites sprites){
		this.game = game;
		this.sprites = sprites;
		
	}
	
	public void update(ArrayList<Enemy> e,  EnemyController ec, Game game){
		for(int i = 0; i < b.size() ; i++){
			bullet = b.get(i);

				for(int ii = 0; ii < e.size(); ii++){
					if(b.get(i).getBounds().intersects(e.get(ii).getBounds())){
						removeBullet(b.get(i));
						game.enemyHealth--;
						if(game.enemyHealth <= 0){
							ec.removeEnemy(e.get(ii));
							game.score ++;
						}
					}					
				}
				
			bullet.update(e);
		}
		
	}
	
	public void render(Graphics g){
		for(int i = 0; i < b.size(); i++){
			bullet = b.get(i);
		
			
			bullet.render(g);
		}
	}
	
	public ArrayList<Bullet> getBulletBounds(){
		return b;
	}
	
	public void addBullet(Bullet bullet){
		b.add(bullet);
	}
	
	public void removeBullet(Bullet bullet){
		b.remove(bullet);
	}
}

Here is the Error i’m getting:

Exception in thread "Thread-2" java.lang.IndexOutOfBoundsException: Index: 5, Size: 5
	at java.util.ArrayList.rangeCheck(Unknown Source)
	at java.util.ArrayList.get(Unknown Source)
	at com.glennbrann.Controllers.BulletController.update(BulletController.java:35)
	at com.glennbrann.Game.Game.update(Game.java:181)
	at com.glennbrann.Game.Game.run(Game.java:129)
	at java.lang.Thread.run(Unknown Source)

Please help thanks :slight_smile:

Didn’t read most of it, but I know as per experience that this might help you.

for(int i = 0; i <= b.size()-1; i++){
         bullet = b.get(i);

            for(int ii = 0; ii <= e.size()-1; ii++){
               if(b.get(i).getBounds().intersects(e.get(ii).getBounds())){
                  removeBullet(b.get(i));
                  game.enemyHealth--;
                  if(game.enemyHealth <= 0){
                     ec.removeEnemy(e.get(ii));
                     game.score ++;
                  }
               }               
            }
            
         bullet.update(e);
}

Everything is so much more fun, if you’re counting the zero.

That Kind of works. it doesn’t work if is use

 for(int ii = 0; ii <= e.size()-1; ii++)

. but it does work when i do this

(int i = 0; i <= b.size()-1; i++)

. But i have one problem. When i shoot the bullet just spawns and doesn’t move. but when i shoot again the previous bullet moves and the next one stays. this happens again and again. Any ideas?

I don’t see any movement code, you might want to post that…

Here is my movement bullet code :

package com.glennbrann.Stuff;

import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;

import com.glennbrann.Controllers.BulletController;
import com.glennbrann.Controllers.EnemyController;
import com.glennbrann.Player.Entity;
import com.glennbrann.Screen.Sprites;

public class Bullet extends Entity{

	Sprites sprites;
	Bullet bullet;
	Enemy enemy;
	EnemyController ec;
	BulletController b;
	ArrayList<Enemy> e;
	ArrayList<Bullet> bul;
	
	
	public Bullet(int x, int y, Sprites sprites) {
		super(x, y);
		this.sprites = sprites;		
	}
	
	public void update(){
		y -= 8;
		if(getX() < 10){
			b.removeBullet(this);
		}
	}
	
	
	public void render(Graphics g){
		g.drawImage(sprites.bullet, x, y, 16, 16, null);
	}
	
	public Rectangle getBounds(){
		return new Rectangle(x,y,16,16);
	}
	
	public void removeBullet(Bullet bullet){
		b.removeBullet(bullet);
	}
	
	public int getX(){
		return x;
	}
	
	public int getY(){
		return y;
	}

}

lolz, we need to see the line @:

com.glennbrann.Controllers.BulletController.update(BulletController.java:35)

Line #35 in BulletController.Java is where the issue is coming from.

i posted it above. but here it is again: public void update(ArrayList e, EnemyController ec, Game game){
for(int i = 0; i < b.size() ; i++){
bullet = b.get(i);

        for(int ii = 0; ii < e.size(); ii++){
           if(b.get(i).getBounds().intersects(e.get(ii).getBounds())){ //line 35
              removeBullet(b.get(i));
              game.enemyHealth--;
              if(game.enemyHealth <= 0){
                 ec.removeEnemy(e.get(ii));
                 game.score ++;
              }
           }               
        }
        
     bullet.update(e);
  }

}

I’m sorry, I just woke up mate.
Didn’t realize you already posted it on OP. >…< thanks.

do you have any idea?

Well, I’m in the process of re-writing it so I can run it in my IDE.
What I have at the moment:
(feel free to replace your method with this one, see if it changes anything ???)


	public void update(ArrayList<Enemy> e, EnemyController ec, Game game) {
		for (Bullet bullet : b) {
			if (b != null) {
				for (Enemy enemy : e) {
					if (enemy != null) {
						if (bullet.getBounds().intersects(enemy.getBounds())) {
							removeBullet(bullet);
							game.enemyHealth--;
							if (game.enemyHealth <= 0) {
								ec.removeEnemy(enemy);
								game.score++;
							}
						}
					}
				}
				bullet.update(e);
			}
		}
	}

i got this error. PS sorry if i’m annoying you with this:

Exception in thread "Thread-2" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
	at java.util.ArrayList$Itr.next(Unknown Source)
	at com.glennbrann.Controllers.BulletController.update(BulletController.java:31)
	at com.glennbrann.Game.Game.update(Game.java:181)
	at com.glennbrann.Game.Game.run(Game.java:129)
	at java.lang.Thread.run(Unknown Source)

dafuq?

pls explain why you think there is a difference between the two lines


for(int i=0; i<10; i++)
for(int i=0; i<=9; i++)

The problem you are having Glenn is that you are removing bullets while you are iterating over it.
i.e. you are deleting the last bullet from your collection at the first enemy, but want to access it again for the next enemy.

You should have written it like this:

public void update(ArrayList<Enemy> e, EnemyController ec, Game game) {
      for (int i = b.size() - 1; i >= 0; i--) {
        Bullet toTest = b.get(i);
            for (Enemy enemy : e) {
                  if (toTest .getBounds().intersects(enemy.getBounds())) {
                     removeBullet(bullet);
                     game.enemyHealth--;
                     if (game.enemyHealth <= 0) {
                        ec.removeEnemy(enemy);
                        game.score++;
                     }
                    continue;//very imported you don't want a bullet to hit multiple enemies
                  }
               }
            }
            bullet.update(e);
         }
      }
   }

ps: I don’t now where this enemy collection is comming from and if it is the same which is in the enemycontroller, because if this would be another bug.

@GabrielBailey74 pls try your code first befor posting, your code will produce an exception

@Danny I’m more than aware of that lolz.
This will fix the exception, and most likely fix his error at the same time :wink:

No worries mate, I’m one of the people here on JGO who like helping people / will take the time :smiley:

Now…
The ConcurrentModificationException is happening due to me changing the ‘for (int i = 0)’ to the 'for (Bullet bullet : b).
I have found a work around for this, but you’ll have to modify your code a little bit…


ArrayList<Bullet> nulledBullets = new ArrayList<Bullet>(); // ADDED
	
	public void update(ArrayList<Enemy> e, EnemyController ec, Game game) {
		if (nulledBullets.size() > 0) {
			for (Bullet nulledBullet : nulledBullets) {
				if (b.contains(nulledBullet)) {
					b.remove(nulledBullet);
				}
			}
			nulledBullets.clear(); // RESET
		}
		for (Bullet bullet : b) {
			if (b != null) {
				for (Enemy enemy : e) {
					if (enemy != null) {
						if (bullet.getBounds().intersects(enemy.getBounds())) {
							if (!nulledBullets.contains(bullet)) {
								nulledBullets.add(bullet); // THIS WILL REMOVE BULLETS WITHOUT A EXCEPTION.
							}
							// removeBullet(bullet); <--- REMOVED TO PREVENT EXCEPTION
							game.enemyHealth--;
							if (game.enemyHealth <= 0) {
								ec.removeEnemy(enemy);
								game.score++;
							}
						}
					}
				}
				bullet.update(e);
			}
		}
	}

the easiest thing is, as I did in the snipped posted by me, to just iterate from the last to the first.

Also Glenn you have a lot of useless fields in your classes, something like the following is just dangerous:


class Foo
{
  Bar coolTempVar;

  void stuff()
  {
    for(int i=0; i<10; ++i)
    {
      coolTempVar = somethingNice();
    }
}

just do:


...
    for(int i=0; i<10; ++i)
    {
      Bar coolTempVar = somethingNice();
    }
...

When i shoot the bullet it progressively get faster and faster each time i shoot it. Also some of the time time the bullets get stuck and i get an error some times

Exception in thread "Thread-2" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
	at java.util.ArrayList$Itr.next(Unknown Source)
	at com.glennbrann.Controllers.BulletController.update(BulletController.java:31)
	at com.glennbrann.Game.Game.update(Game.java:181)
	at com.glennbrann.Game.Game.run(Game.java:129)
	at java.lang.Thread.run(Unknown Source)

line 31 is

for (Enemy enemy : e) {

Thanks again

Yes i get what you mean. Good tip. i’m still learning though :slight_smile:

Well, we just fixed the exception for the Bullet being removed.

NOTE
: The enemy’s below are being removed from the ArrayList that’s passed through as a parameter in the method.

Now we have to fix for the Enemy being removed:
(NO MORE EXCEPTIONS :P)


	ArrayList<Bullet> nulledBullets = new ArrayList<Bullet>();
	ArrayList<Enemy> nulledEnemys = new ArrayList<Enemy>();
	
	public void update(ArrayList<Enemy> e, EnemyController ec, Game game) {
		if (nulledEnemys.size() > 0) {
			for (Enemy nulledEnemy : nulledEnemys) {
				if (e.contains(nulledEnemy)) {
					e.remove(nulledEnemy);
				}
			}
			nulledEnemys.clear();
		}
		if (nulledBullets.size() > 0) {
			for (Bullet nulledBullet : nulledBullets) {
				if (b.contains(nulledBullet)) {
					b.remove(nulledBullet);
				}
			}
			nulledBullets.clear();
		}
		for (Bullet bullet : b) {
			if (b != null) {
				for (Enemy enemy : e) {
					if (enemy != null) {
						if (bullet.getBounds().intersects(enemy.getBounds())) {
							if (!nulledBullets.contains(bullet)) {
								nulledBullets.add(bullet); // THIS WILL REMOVE BULLETS.
							}
							// removeBullet(bullet); <--- REMOVED
							game.enemyHealth--;
							if (game.enemyHealth <= 0) {
								if (!nulledEnemys.contains(enemy)) {
									nulledEnemys.add(enemy); // THIS WILL REMOVE ENEMYS.
								}
								// ec.removeEnemy(enemy); <--- REMOVED
								game.score++;
							}
						}
					}
				}
				bullet.update(e);
			}
		}
	}

i am getting yet another ConcurrentModificationException

   public void update(ArrayList<Enemy> e,  EnemyController ec, Game game){
      List<Bullet> tempAList = new ArrayList<Bullet>( b.size() );
      for (  Bullet bullet : b ) {

            for (Enemy enemy : e) {

               if ( bullet.getBounds().intersects( enemy.getBounds() ) ) {

                  game.enemyHealth--;

                  if ( game.enemyHealth <= 0 ) {

                     ec.removeEnemy( enemy );
                     game.score ++;

                  }
               } else {
                   tempAList.add( bullet );
               }
            }
            
         bullet.update(e);
      }

      b.clear();
      b = tempAList;
      tempAList = null;
   }

A shot in the dark.

Thank you so much. its working now :slight_smile: [Just not sure how that works though.] would you mind maybe explain it. if not its fine